Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws\Api\Parser;
3
 
4
use Aws\Api\DateTimeResult;
5
use Aws\Api\ListShape;
6
use Aws\Api\MapShape;
7
use Aws\Api\Parser\Exception\ParserException;
8
use Aws\Api\Shape;
9
use Aws\Api\StructureShape;
10
 
11
/**
12
 * @internal Implements standard XML parsing for REST-XML and Query protocols.
13
 */
14
class XmlParser
15
{
16
    public function parse(StructureShape $shape, \SimpleXMLElement $value)
17
    {
18
        return $this->dispatch($shape, $value);
19
    }
20
 
21
    private function dispatch($shape, \SimpleXMLElement $value)
22
    {
23
        static $methods = [
24
            'structure' => 'parse_structure',
25
            'list'      => 'parse_list',
26
            'map'       => 'parse_map',
27
            'blob'      => 'parse_blob',
28
            'boolean'   => 'parse_boolean',
29
            'integer'   => 'parse_integer',
30
            'float'     => 'parse_float',
31
            'double'    => 'parse_float',
32
            'timestamp' => 'parse_timestamp',
33
        ];
34
 
35
        $type = $shape['type'];
36
        if (isset($methods[$type])) {
37
            return $this->{$methods[$type]}($shape, $value);
38
        }
39
 
40
        return (string) $value;
41
    }
42
 
43
    private function parse_structure(
44
        StructureShape $shape,
45
        \SimpleXMLElement $value
46
    ) {
47
        $target = [];
48
 
49
        foreach ($shape->getMembers() as $name => $member) {
50
            // Extract the name of the XML node
51
            $node = $this->memberKey($member, $name);
52
            if (isset($value->{$node})) {
53
                $target[$name] = $this->dispatch($member, $value->{$node});
54
            } else {
55
                $memberShape = $shape->getMember($name);
56
                if (!empty($memberShape['xmlAttribute'])) {
57
                    $target[$name] = $this->parse_xml_attribute(
58
                        $shape,
59
                        $memberShape,
60
                        $value
61
                    );
62
                }
63
            }
64
        }
65
        if (isset($shape['union'])
66
            && $shape['union']
67
            && empty($target)
68
        ) {
69
            foreach ($value as $key => $val) {
70
                $name = $val->children()->getName();
71
                $target['Unknown'][$name] = $val->$name;
72
            }
73
        }
74
        return $target;
75
    }
76
 
77
    private function memberKey(Shape $shape, $name)
78
    {
79
        if (null !== $shape['locationName']) {
80
            return $shape['locationName'];
81
        }
82
 
83
        if ($shape instanceof ListShape && $shape['flattened']) {
84
            return $shape->getMember()['locationName'] ?: $name;
85
        }
86
 
87
        return $name;
88
    }
89
 
90
    private function parse_list(ListShape $shape, \SimpleXMLElement  $value)
91
    {
92
        $target = [];
93
        $member = $shape->getMember();
94
 
95
        if (!$shape['flattened']) {
96
            $value = $value->{$member['locationName'] ?: 'member'};
97
        }
98
 
99
        foreach ($value as $v) {
100
            $target[] = $this->dispatch($member, $v);
101
        }
102
 
103
        return $target;
104
    }
105
 
106
    private function parse_map(MapShape $shape, \SimpleXMLElement $value)
107
    {
108
        $target = [];
109
 
110
        if (!$shape['flattened']) {
111
            $value = $value->entry;
112
        }
113
 
114
        $mapKey = $shape->getKey();
115
        $mapValue = $shape->getValue();
116
        $keyName = $shape->getKey()['locationName'] ?: 'key';
117
        $valueName = $shape->getValue()['locationName'] ?: 'value';
118
 
119
        foreach ($value as $node) {
120
            $key = $this->dispatch($mapKey, $node->{$keyName});
121
            $value = $this->dispatch($mapValue, $node->{$valueName});
122
            $target[$key] = $value;
123
        }
124
 
125
        return $target;
126
    }
127
 
128
    private function parse_blob(Shape $shape, $value)
129
    {
130
        return base64_decode((string) $value);
131
    }
132
 
133
    private function parse_float(Shape $shape, $value)
134
    {
135
        return (float) (string) $value;
136
    }
137
 
138
    private function parse_integer(Shape $shape, $value)
139
    {
140
        return (int) (string) $value;
141
    }
142
 
143
    private function parse_boolean(Shape $shape, $value)
144
    {
145
        return $value == 'true';
146
    }
147
 
148
    private function parse_timestamp(Shape $shape, $value)
149
    {
150
        if (is_string($value)
151
            || is_int($value)
152
            || (is_object($value)
153
                && method_exists($value, '__toString'))
154
        ) {
155
            return DateTimeResult::fromTimestamp(
156
                (string) $value,
157
                !empty($shape['timestampFormat']) ? $shape['timestampFormat'] : null
158
            );
159
        }
160
        throw new ParserException('Invalid timestamp value passed to XmlParser::parse_timestamp');
161
    }
162
 
163
    private function parse_xml_attribute(Shape $shape, Shape $memberShape, $value)
164
    {
165
        $namespace = $shape['xmlNamespace']['uri']
166
            ? $shape['xmlNamespace']['uri']
167
            : '';
168
        $prefix = $shape['xmlNamespace']['prefix']
169
            ? $shape['xmlNamespace']['prefix']
170
            : '';
171
        if (!empty($prefix)) {
172
            $prefix .= ':';
173
        }
174
        $key = str_replace($prefix, '', $memberShape['locationName']);
175
 
176
        $attributes = $value->attributes($namespace);
177
        return isset($attributes[$key]) ? (string) $attributes[$key] : null;
178
    }
179
}