mirror of
https://github.com/SociallyDev/Spaces-API.git
synced 2025-08-14 02:27:23 -07:00
spaces.php
This commit is contained in:
parent
7755490b81
commit
eefa32741e
845 changed files with 50409 additions and 0 deletions
40
aws/Aws/Api/Serializer/Ec2ParamBuilder.php
Normal file
40
aws/Aws/Api/Serializer/Ec2ParamBuilder.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\ListShape;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Ec2ParamBuilder extends QueryParamBuilder
|
||||
{
|
||||
protected function queryName(Shape $shape, $default = null)
|
||||
{
|
||||
return ($shape['queryName']
|
||||
?: ucfirst($shape['locationName']))
|
||||
?: $default;
|
||||
}
|
||||
|
||||
protected function isFlat(Shape $shape)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function format_list(
|
||||
ListShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
&$query
|
||||
) {
|
||||
// Handle empty list serialization
|
||||
if (!$value) {
|
||||
$query[$prefix] = false;
|
||||
} else {
|
||||
$items = $shape->getMember();
|
||||
foreach ($value as $k => $v) {
|
||||
$this->format($items, $v, $prefix . '.' . ($k + 1), $query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
90
aws/Aws/Api/Serializer/JsonBody.php
Normal file
90
aws/Aws/Api/Serializer/JsonBody.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\TimestampShape;
|
||||
|
||||
/**
|
||||
* Formats the JSON body of a JSON-REST or JSON-RPC operation.
|
||||
* @internal
|
||||
*/
|
||||
class JsonBody
|
||||
{
|
||||
private $api;
|
||||
|
||||
public function __construct(Service $api)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the JSON Content-Type header for a service API
|
||||
*
|
||||
* @param Service $service
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getContentType(Service $service)
|
||||
{
|
||||
return 'application/x-amz-json-'
|
||||
. number_format($service->getMetadata('jsonVersion'), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the JSON body based on an array of arguments.
|
||||
*
|
||||
* @param Shape $shape Operation being constructed
|
||||
* @param array $args Associative array of arguments
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function build(Shape $shape, array $args)
|
||||
{
|
||||
$result = json_encode($this->format($shape, $args));
|
||||
|
||||
return $result == '[]' ? '{}' : $result;
|
||||
}
|
||||
|
||||
private function format(Shape $shape, $value)
|
||||
{
|
||||
switch ($shape['type']) {
|
||||
case 'structure':
|
||||
$data = [];
|
||||
foreach ($value as $k => $v) {
|
||||
if ($v !== null && $shape->hasMember($k)) {
|
||||
$valueShape = $shape->getMember($k);
|
||||
$data[$valueShape['locationName'] ?: $k]
|
||||
= $this->format($valueShape, $v);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
|
||||
case 'list':
|
||||
$items = $shape->getMember();
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = $this->format($items, $v);
|
||||
}
|
||||
return $value;
|
||||
|
||||
case 'map':
|
||||
if (empty($value)) {
|
||||
return new \stdClass;
|
||||
}
|
||||
$values = $shape->getValue();
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = $this->format($values, $v);
|
||||
}
|
||||
return $value;
|
||||
|
||||
case 'blob':
|
||||
return base64_encode($value);
|
||||
|
||||
case 'timestamp':
|
||||
return TimestampShape::format($value, 'unixTimestamp');
|
||||
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
69
aws/Aws/Api/Serializer/JsonRpcSerializer.php
Normal file
69
aws/Aws/Api/Serializer/JsonRpcSerializer.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\CommandInterface;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Prepares a JSON-RPC request for transfer.
|
||||
* @internal
|
||||
*/
|
||||
class JsonRpcSerializer
|
||||
{
|
||||
/** @var JsonBody */
|
||||
private $jsonFormatter;
|
||||
|
||||
/** @var string */
|
||||
private $endpoint;
|
||||
|
||||
/** @var Service */
|
||||
private $api;
|
||||
|
||||
/** @var string */
|
||||
private $contentType;
|
||||
|
||||
/**
|
||||
* @param Service $api Service description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
* @param JsonBody $jsonFormatter Optional JSON formatter to use
|
||||
*/
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
JsonBody $jsonFormatter = null
|
||||
) {
|
||||
$this->endpoint = $endpoint;
|
||||
$this->api = $api;
|
||||
$this->jsonFormatter = $jsonFormatter ?: new JsonBody($this->api);
|
||||
$this->contentType = JsonBody::getContentType($api);
|
||||
}
|
||||
|
||||
/**
|
||||
* When invoked with an AWS command, returns a serialization array
|
||||
* containing "method", "uri", "headers", and "body" key value pairs.
|
||||
*
|
||||
* @param CommandInterface $command
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function __invoke(CommandInterface $command)
|
||||
{
|
||||
$name = $command->getName();
|
||||
$operation = $this->api->getOperation($name);
|
||||
|
||||
return new Request(
|
||||
$operation['http']['method'],
|
||||
$this->endpoint,
|
||||
[
|
||||
'X-Amz-Target' => $this->api->getMetadata('targetPrefix') . '.' . $name,
|
||||
'Content-Type' => $this->contentType
|
||||
],
|
||||
$this->jsonFormatter->build(
|
||||
$operation->getInput(),
|
||||
$command->toArray()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
154
aws/Aws/Api/Serializer/QueryParamBuilder.php
Normal file
154
aws/Aws/Api/Serializer/QueryParamBuilder.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\ListShape;
|
||||
use Aws\Api\MapShape;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\TimestampShape;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class QueryParamBuilder
|
||||
{
|
||||
private $methods;
|
||||
|
||||
protected function queryName(Shape $shape, $default = null)
|
||||
{
|
||||
if (null !== $shape['queryName']) {
|
||||
return $shape['queryName'];
|
||||
}
|
||||
|
||||
if (null !== $shape['locationName']) {
|
||||
return $shape['locationName'];
|
||||
}
|
||||
|
||||
if ($this->isFlat($shape) && !empty($shape['member']['locationName'])) {
|
||||
return $shape['member']['locationName'];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
protected function isFlat(Shape $shape)
|
||||
{
|
||||
return $shape['flattened'] === true;
|
||||
}
|
||||
|
||||
public function __invoke(StructureShape $shape, array $params)
|
||||
{
|
||||
if (!$this->methods) {
|
||||
$this->methods = array_fill_keys(get_class_methods($this), true);
|
||||
}
|
||||
|
||||
$query = [];
|
||||
$this->format_structure($shape, $params, '', $query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function format(Shape $shape, $value, $prefix, array &$query)
|
||||
{
|
||||
$type = 'format_' . $shape['type'];
|
||||
if (isset($this->methods[$type])) {
|
||||
$this->{$type}($shape, $value, $prefix, $query);
|
||||
} else {
|
||||
$query[$prefix] = (string) $value;
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_structure(
|
||||
StructureShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
&$query
|
||||
) {
|
||||
if ($prefix) {
|
||||
$prefix .= '.';
|
||||
}
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
if ($shape->hasMember($k)) {
|
||||
$member = $shape->getMember($k);
|
||||
$this->format(
|
||||
$member,
|
||||
$v,
|
||||
$prefix . $this->queryName($member, $k),
|
||||
$query
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_list(
|
||||
ListShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
&$query
|
||||
) {
|
||||
// Handle empty list serialization
|
||||
if (!$value) {
|
||||
$query[$prefix] = '';
|
||||
return;
|
||||
}
|
||||
|
||||
$items = $shape->getMember();
|
||||
|
||||
if (!$this->isFlat($shape)) {
|
||||
$locationName = $shape->getMember()['locationName'] ?: 'member';
|
||||
$prefix .= ".$locationName";
|
||||
} elseif ($name = $this->queryName($items)) {
|
||||
$parts = explode('.', $prefix);
|
||||
$parts[count($parts) - 1] = $name;
|
||||
$prefix = implode('.', $parts);
|
||||
}
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
$this->format($items, $v, $prefix . '.' . ($k + 1), $query);
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_map(
|
||||
MapShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
array &$query
|
||||
) {
|
||||
$vals = $shape->getValue();
|
||||
$keys = $shape->getKey();
|
||||
|
||||
if (!$this->isFlat($shape)) {
|
||||
$prefix .= '.entry';
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$keyName = '%s.%d.' . $this->queryName($keys, 'key');
|
||||
$valueName = '%s.%s.' . $this->queryName($vals, 'value');
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
$i++;
|
||||
$this->format($keys, $k, sprintf($keyName, $prefix, $i), $query);
|
||||
$this->format($vals, $v, sprintf($valueName, $prefix, $i), $query);
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_blob(Shape $shape, $value, $prefix, array &$query)
|
||||
{
|
||||
$query[$prefix] = base64_encode($value);
|
||||
}
|
||||
|
||||
protected function format_timestamp(
|
||||
TimestampShape $shape,
|
||||
$value,
|
||||
$prefix,
|
||||
array &$query
|
||||
) {
|
||||
$query[$prefix] = TimestampShape::format($value, 'iso8601');
|
||||
}
|
||||
|
||||
protected function format_boolean(Shape $shape, $value, $prefix, array &$query)
|
||||
{
|
||||
$query[$prefix] = ($value) ? 'true' : 'false';
|
||||
}
|
||||
}
|
69
aws/Aws/Api/Serializer/QuerySerializer.php
Normal file
69
aws/Aws/Api/Serializer/QuerySerializer.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\CommandInterface;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Serializes a query protocol request.
|
||||
* @internal
|
||||
*/
|
||||
class QuerySerializer
|
||||
{
|
||||
private $endpoint;
|
||||
private $api;
|
||||
private $paramBuilder;
|
||||
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
callable $paramBuilder = null
|
||||
) {
|
||||
$this->api = $api;
|
||||
$this->endpoint = $endpoint;
|
||||
$this->paramBuilder = $paramBuilder ?: new QueryParamBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* When invoked with an AWS command, returns a serialization array
|
||||
* containing "method", "uri", "headers", and "body" key value pairs.
|
||||
*
|
||||
* @param CommandInterface $command
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function __invoke(CommandInterface $command)
|
||||
{
|
||||
$operation = $this->api->getOperation($command->getName());
|
||||
|
||||
$body = [
|
||||
'Action' => $command->getName(),
|
||||
'Version' => $this->api->getMetadata('apiVersion')
|
||||
];
|
||||
|
||||
$params = $command->toArray();
|
||||
|
||||
// Only build up the parameters when there are parameters to build
|
||||
if ($params) {
|
||||
$body += call_user_func(
|
||||
$this->paramBuilder,
|
||||
$operation->getInput(),
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
$body = http_build_query($body, null, '&', PHP_QUERY_RFC3986);
|
||||
|
||||
return new Request(
|
||||
'POST',
|
||||
$this->endpoint,
|
||||
[
|
||||
'Content-Length' => strlen($body),
|
||||
'Content-Type' => 'application/x-www-form-urlencoded'
|
||||
],
|
||||
$body
|
||||
);
|
||||
}
|
||||
}
|
39
aws/Aws/Api/Serializer/RestJsonSerializer.php
Normal file
39
aws/Aws/Api/Serializer/RestJsonSerializer.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
|
||||
/**
|
||||
* Serializes requests for the REST-JSON protocol.
|
||||
* @internal
|
||||
*/
|
||||
class RestJsonSerializer extends RestSerializer
|
||||
{
|
||||
/** @var JsonBody */
|
||||
private $jsonFormatter;
|
||||
|
||||
/** @var string */
|
||||
private $contentType;
|
||||
|
||||
/**
|
||||
* @param Service $api Service API description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
* @param JsonBody $jsonFormatter Optional JSON formatter to use
|
||||
*/
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
JsonBody $jsonFormatter = null
|
||||
) {
|
||||
parent::__construct($api, $endpoint);
|
||||
$this->contentType = JsonBody::getContentType($api);
|
||||
$this->jsonFormatter = $jsonFormatter ?: new JsonBody($api);
|
||||
}
|
||||
|
||||
protected function payload(StructureShape $member, array $value, array &$opts)
|
||||
{
|
||||
$opts['headers']['Content-Type'] = $this->contentType;
|
||||
$opts['body'] = (string) $this->jsonFormatter->build($member, $value);
|
||||
}
|
||||
}
|
208
aws/Aws/Api/Serializer/RestSerializer.php
Normal file
208
aws/Aws/Api/Serializer/RestSerializer.php
Normal file
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\MapShape;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\Operation;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\TimestampShape;
|
||||
use Aws\CommandInterface;
|
||||
use GuzzleHttp\Psr7;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use GuzzleHttp\Psr7\UriResolver;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Serializes HTTP locations like header, uri, payload, etc...
|
||||
* @internal
|
||||
*/
|
||||
abstract class RestSerializer
|
||||
{
|
||||
/** @var Service */
|
||||
private $api;
|
||||
|
||||
/** @var Psr7\Uri */
|
||||
private $endpoint;
|
||||
|
||||
/**
|
||||
* @param Service $api Service API description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
*/
|
||||
public function __construct(Service $api, $endpoint)
|
||||
{
|
||||
$this->api = $api;
|
||||
$this->endpoint = Psr7\uri_for($endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command Command to serialized
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function __invoke(CommandInterface $command)
|
||||
{
|
||||
$operation = $this->api->getOperation($command->getName());
|
||||
$args = $command->toArray();
|
||||
$opts = $this->serialize($operation, $args);
|
||||
$uri = $this->buildEndpoint($operation, $args, $opts);
|
||||
|
||||
return new Psr7\Request(
|
||||
$operation['http']['method'],
|
||||
$uri,
|
||||
isset($opts['headers']) ? $opts['headers'] : [],
|
||||
isset($opts['body']) ? $opts['body'] : null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies a hash of request options for a payload body.
|
||||
*
|
||||
* @param StructureShape $member Member to serialize
|
||||
* @param array $value Value to serialize
|
||||
* @param array $opts Request options to modify.
|
||||
*/
|
||||
abstract protected function payload(
|
||||
StructureShape $member,
|
||||
array $value,
|
||||
array &$opts
|
||||
);
|
||||
|
||||
private function serialize(Operation $operation, array $args)
|
||||
{
|
||||
$opts = [];
|
||||
$input = $operation->getInput();
|
||||
|
||||
// Apply the payload trait if present
|
||||
if ($payload = $input['payload']) {
|
||||
$this->applyPayload($input, $payload, $args, $opts);
|
||||
}
|
||||
|
||||
foreach ($args as $name => $value) {
|
||||
if ($input->hasMember($name)) {
|
||||
$member = $input->getMember($name);
|
||||
$location = $member['location'];
|
||||
if (!$payload && !$location) {
|
||||
$bodyMembers[$name] = $value;
|
||||
} elseif ($location == 'header') {
|
||||
$this->applyHeader($name, $member, $value, $opts);
|
||||
} elseif ($location == 'querystring') {
|
||||
$this->applyQuery($name, $member, $value, $opts);
|
||||
} elseif ($location == 'headers') {
|
||||
$this->applyHeaderMap($name, $member, $value, $opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($bodyMembers)) {
|
||||
$this->payload($operation->getInput(), $bodyMembers, $opts);
|
||||
}
|
||||
|
||||
return $opts;
|
||||
}
|
||||
|
||||
private function applyPayload(StructureShape $input, $name, array $args, array &$opts)
|
||||
{
|
||||
if (!isset($args[$name])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$m = $input->getMember($name);
|
||||
|
||||
if ($m['streaming'] ||
|
||||
($m['type'] == 'string' || $m['type'] == 'blob')
|
||||
) {
|
||||
// Streaming bodies or payloads that are strings are
|
||||
// always just a stream of data.
|
||||
$opts['body'] = Psr7\stream_for($args[$name]);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->payload($m, $args[$name], $opts);
|
||||
}
|
||||
|
||||
private function applyHeader($name, Shape $member, $value, array &$opts)
|
||||
{
|
||||
if ($member->getType() == 'timestamp') {
|
||||
$value = TimestampShape::format($value, 'rfc822');
|
||||
}
|
||||
if ($member['jsonvalue']) {
|
||||
$value = json_encode($value);
|
||||
if (empty($value) && JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new \InvalidArgumentException('Unable to encode the provided value'
|
||||
. ' with \'json_encode\'. ' . json_last_error_msg());
|
||||
}
|
||||
|
||||
$value = base64_encode($value);
|
||||
}
|
||||
|
||||
$opts['headers'][$member['locationName'] ?: $name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This is currently only present in the Amazon S3 model.
|
||||
*/
|
||||
private function applyHeaderMap($name, Shape $member, array $value, array &$opts)
|
||||
{
|
||||
$prefix = $member['locationName'];
|
||||
foreach ($value as $k => $v) {
|
||||
$opts['headers'][$prefix . $k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
private function applyQuery($name, Shape $member, $value, array &$opts)
|
||||
{
|
||||
if ($member instanceof MapShape) {
|
||||
$opts['query'] = isset($opts['query']) && is_array($opts['query'])
|
||||
? $opts['query'] + $value
|
||||
: $value;
|
||||
} elseif ($value !== null) {
|
||||
if ($member->getType() === 'boolean') {
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
$opts['query'][$member['locationName'] ?: $name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
private function buildEndpoint(Operation $operation, array $args, array $opts)
|
||||
{
|
||||
$varspecs = [];
|
||||
|
||||
// Create an associative array of varspecs used in expansions
|
||||
foreach ($operation->getInput()->getMembers() as $name => $member) {
|
||||
if ($member['location'] == 'uri') {
|
||||
$varspecs[$member['locationName'] ?: $name] =
|
||||
isset($args[$name])
|
||||
? $args[$name]
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
$relative = preg_replace_callback(
|
||||
'/\{([^\}]+)\}/',
|
||||
function (array $matches) use ($varspecs) {
|
||||
$isGreedy = substr($matches[1], -1, 1) == '+';
|
||||
$k = $isGreedy ? substr($matches[1], 0, -1) : $matches[1];
|
||||
if (!isset($varspecs[$k])) {
|
||||
return '';
|
||||
} elseif ($isGreedy) {
|
||||
return str_replace('%2F', '/', rawurlencode($varspecs[$k]));
|
||||
} else {
|
||||
return rawurlencode($varspecs[$k]);
|
||||
}
|
||||
},
|
||||
$operation['http']['requestUri']
|
||||
);
|
||||
|
||||
// Add the query string variables or appending to one if needed.
|
||||
if (!empty($opts['query'])) {
|
||||
$append = Psr7\build_query($opts['query']);
|
||||
$relative .= strpos($relative, '?') ? "&{$append}" : "?$append";
|
||||
}
|
||||
|
||||
// Expand path place holders using Amazon's slightly different URI
|
||||
// template syntax.
|
||||
return UriResolver::resolve($this->endpoint, new Uri($relative));
|
||||
}
|
||||
}
|
34
aws/Aws/Api/Serializer/RestXmlSerializer.php
Normal file
34
aws/Aws/Api/Serializer/RestXmlSerializer.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\Service;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class RestXmlSerializer extends RestSerializer
|
||||
{
|
||||
/** @var XmlBody */
|
||||
private $xmlBody;
|
||||
|
||||
/**
|
||||
* @param Service $api Service API description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
* @param XmlBody $xmlBody Optional XML formatter to use
|
||||
*/
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
XmlBody $xmlBody = null
|
||||
) {
|
||||
parent::__construct($api, $endpoint);
|
||||
$this->xmlBody = $xmlBody ?: new XmlBody($api);
|
||||
}
|
||||
|
||||
protected function payload(StructureShape $member, array $value, array &$opts)
|
||||
{
|
||||
$opts['headers']['Content-Type'] = 'application/xml';
|
||||
$opts['body'] = (string) $this->xmlBody->build($member, $value);
|
||||
}
|
||||
}
|
217
aws/Aws/Api/Serializer/XmlBody.php
Normal file
217
aws/Aws/Api/Serializer/XmlBody.php
Normal file
|
@ -0,0 +1,217 @@
|
|||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\MapShape;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\ListShape;
|
||||
use Aws\Api\TimestampShape;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal Formats the XML body of a REST-XML services.
|
||||
*/
|
||||
class XmlBody
|
||||
{
|
||||
/** @var \Aws\Api\Service */
|
||||
private $api;
|
||||
|
||||
/**
|
||||
* @param Service $api API being used to create the XML body.
|
||||
*/
|
||||
public function __construct(Service $api)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the XML body based on an array of arguments.
|
||||
*
|
||||
* @param Shape $shape Operation being constructed
|
||||
* @param array $args Associative array of arguments
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function build(Shape $shape, array $args)
|
||||
{
|
||||
$xml = new XMLWriter();
|
||||
$xml->openMemory();
|
||||
$xml->startDocument('1.0', 'UTF-8');
|
||||
$this->format($shape, $shape['locationName'] ?: $shape['name'], $args, $xml);
|
||||
$xml->endDocument();
|
||||
|
||||
return $xml->outputMemory();
|
||||
}
|
||||
|
||||
private function startElement(Shape $shape, $name, XMLWriter $xml)
|
||||
{
|
||||
$xml->startElement($name);
|
||||
|
||||
if ($ns = $shape['xmlNamespace']) {
|
||||
$xml->writeAttribute(
|
||||
isset($ns['prefix']) ? "xmlns:{$ns['prefix']}" : 'xmlns',
|
||||
$shape['xmlNamespace']['uri']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function format(Shape $shape, $name, $value, XMLWriter $xml)
|
||||
{
|
||||
// Any method mentioned here has a custom serialization handler.
|
||||
static $methods = [
|
||||
'add_structure' => true,
|
||||
'add_list' => true,
|
||||
'add_blob' => true,
|
||||
'add_timestamp' => true,
|
||||
'add_boolean' => true,
|
||||
'add_map' => true,
|
||||
'add_string' => true
|
||||
];
|
||||
|
||||
$type = 'add_' . $shape['type'];
|
||||
if (isset($methods[$type])) {
|
||||
$this->{$type}($shape, $name, $value, $xml);
|
||||
} else {
|
||||
$this->defaultShape($shape, $name, $value, $xml);
|
||||
}
|
||||
}
|
||||
|
||||
private function defaultShape(Shape $shape, $name, $value, XMLWriter $xml)
|
||||
{
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$xml->writeRaw($value);
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_structure(
|
||||
StructureShape $shape,
|
||||
$name,
|
||||
array $value,
|
||||
\XMLWriter $xml
|
||||
) {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
|
||||
foreach ($this->getStructureMembers($shape, $value) as $k => $definition) {
|
||||
$this->format(
|
||||
$definition['member'],
|
||||
$definition['member']['locationName'] ?: $k,
|
||||
$definition['value'],
|
||||
$xml
|
||||
);
|
||||
}
|
||||
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function getStructureMembers(StructureShape $shape, array $value)
|
||||
{
|
||||
$members = [];
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
if ($v !== null && $shape->hasMember($k)) {
|
||||
$definition = [
|
||||
'member' => $shape->getMember($k),
|
||||
'value' => $v,
|
||||
];
|
||||
|
||||
if ($definition['member']['xmlAttribute']) {
|
||||
// array_unshift_associative
|
||||
$members = [$k => $definition] + $members;
|
||||
} else {
|
||||
$members[$k] = $definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $members;
|
||||
}
|
||||
|
||||
private function add_list(
|
||||
ListShape $shape,
|
||||
$name,
|
||||
array $value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$items = $shape->getMember();
|
||||
|
||||
if ($shape['flattened']) {
|
||||
$elementName = $name;
|
||||
} else {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$elementName = $items['locationName'] ?: 'member';
|
||||
}
|
||||
|
||||
foreach ($value as $v) {
|
||||
$this->format($items, $elementName, $v, $xml);
|
||||
}
|
||||
|
||||
if (!$shape['flattened']) {
|
||||
$xml->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
private function add_map(
|
||||
MapShape $shape,
|
||||
$name,
|
||||
array $value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$xmlEntry = $shape['flattened'] ? $shape['locationName'] : 'entry';
|
||||
$xmlKey = $shape->getKey()['locationName'] ?: 'key';
|
||||
$xmlValue = $shape->getValue()['locationName'] ?: 'value';
|
||||
|
||||
$this->startElement($shape, $name, $xml);
|
||||
|
||||
foreach ($value as $key => $v) {
|
||||
$this->startElement($shape, $xmlEntry, $xml);
|
||||
$this->format($shape->getKey(), $xmlKey, $key, $xml);
|
||||
$this->format($shape->getValue(), $xmlValue, $v, $xml);
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_blob(Shape $shape, $name, $value, XMLWriter $xml)
|
||||
{
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$xml->writeRaw(base64_encode($value));
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_timestamp(
|
||||
TimestampShape $shape,
|
||||
$name,
|
||||
$value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$xml->writeRaw(TimestampShape::format($value, 'iso8601'));
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_boolean(
|
||||
Shape $shape,
|
||||
$name,
|
||||
$value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$xml->writeRaw($value ? 'true' : 'false');
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_string(
|
||||
Shape $shape,
|
||||
$name,
|
||||
$value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
if ($shape['xmlAttribute']) {
|
||||
$xml->writeAttribute($shape['locationName'] ?: $name, $value);
|
||||
} else {
|
||||
$this->defaultShape($shape, $name, $value, $xml);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue