123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <?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->text($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);
- $timestampFormat = !empty($shape['timestampFormat'])
- ? $shape['timestampFormat']
- : 'iso8601';
- $xml->writeRaw(TimestampShape::format($value, $timestampFormat));
- $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);
- }
- }
- }
|