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\Shape;
6
use Aws\Api\StructureShape;
7
use Aws\Result;
8
use Aws\CommandInterface;
9
use Psr\Http\Message\ResponseInterface;
10
 
11
/**
12
 * @internal
13
 */
14
abstract class AbstractRestParser extends AbstractParser
15
{
16
    use PayloadParserTrait;
17
 
18
    /**
19
     * Parses a payload from a response.
20
     *
21
     * @param ResponseInterface $response Response to parse.
22
     * @param StructureShape    $member   Member to parse
23
     * @param array             $result   Result value
24
     *
25
     * @return mixed
26
     */
27
    abstract protected function payload(
28
        ResponseInterface $response,
29
        StructureShape $member,
30
        array &$result
31
    );
32
 
33
    public function __invoke(
34
        CommandInterface $command,
35
        ResponseInterface $response
36
    ) {
37
        $output = $this->api->getOperation($command->getName())->getOutput();
38
        $result = [];
39
 
40
        if ($payload = $output['payload']) {
41
            $this->extractPayload($payload, $output, $response, $result);
42
        }
43
 
44
        foreach ($output->getMembers() as $name => $member) {
45
            switch ($member['location']) {
46
                case 'header':
47
                    $this->extractHeader($name, $member, $response, $result);
48
                    break;
49
                case 'headers':
50
                    $this->extractHeaders($name, $member, $response, $result);
51
                    break;
52
                case 'statusCode':
53
                    $this->extractStatus($name, $response, $result);
54
                    break;
55
            }
56
        }
57
 
58
        if (!$payload
59
            && $response->getBody()->getSize() > 0
60
            && count($output->getMembers()) > 0
61
        ) {
62
            // if no payload was found, then parse the contents of the body
63
            $this->payload($response, $output, $result);
64
        }
65
 
66
        return new Result($result);
67
    }
68
 
69
    private function extractPayload(
70
        $payload,
71
        StructureShape $output,
72
        ResponseInterface $response,
73
        array &$result
74
    ) {
75
        $member = $output->getMember($payload);
76
 
77
        if (!empty($member['eventstream'])) {
78
            $result[$payload] = new EventParsingIterator(
79
                $response->getBody(),
80
                $member,
81
                $this
82
            );
83
        } else if ($member instanceof StructureShape) {
84
            // Structure members parse top-level data into a specific key.
85
            $result[$payload] = [];
86
            $this->payload($response, $member, $result[$payload]);
87
        } else {
88
            // Streaming data is just the stream from the response body.
89
            $result[$payload] = $response->getBody();
90
        }
91
    }
92
 
93
    /**
94
     * Extract a single header from the response into the result.
95
     */
96
    private function extractHeader(
97
        $name,
98
        Shape $shape,
99
        ResponseInterface $response,
100
        &$result
101
    ) {
102
        $value = $response->getHeaderLine($shape['locationName'] ?: $name);
103
 
104
        switch ($shape->getType()) {
105
            case 'float':
106
            case 'double':
107
                $value = (float) $value;
108
                break;
109
            case 'long':
110
                $value = (int) $value;
111
                break;
112
            case 'boolean':
113
                $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
114
                break;
115
            case 'blob':
116
                $value = base64_decode($value);
117
                break;
118
            case 'timestamp':
119
                try {
120
                    $value = DateTimeResult::fromTimestamp(
121
                        $value,
122
                        !empty($shape['timestampFormat']) ? $shape['timestampFormat'] : null
123
                    );
124
                    break;
125
                } catch (\Exception $e) {
126
                    // If the value cannot be parsed, then do not add it to the
127
                    // output structure.
128
                    return;
129
                }
130
            case 'string':
131
                try {
132
                    if ($shape['jsonvalue']) {
133
                        $value = $this->parseJson(base64_decode($value), $response);
134
                    }
135
 
136
                    // If value is not set, do not add to output structure.
137
                    if (!isset($value)) {
138
                        return;
139
                    }
140
                    break;
141
                } catch (\Exception $e) {
142
                    //If the value cannot be parsed, then do not add it to the
143
                    //output structure.
144
                    return;
145
                }
146
        }
147
 
148
        $result[$name] = $value;
149
    }
150
 
151
    /**
152
     * Extract a map of headers with an optional prefix from the response.
153
     */
154
    private function extractHeaders(
155
        $name,
156
        Shape $shape,
157
        ResponseInterface $response,
158
        &$result
159
    ) {
160
        // Check if the headers are prefixed by a location name
161
        $result[$name] = [];
162
        $prefix = $shape['locationName'];
163
        $prefixLen = $prefix !== null ? strlen($prefix) : 0;
164
 
165
        foreach ($response->getHeaders() as $k => $values) {
166
            if (!$prefixLen) {
167
                $result[$name][$k] = implode(', ', $values);
168
            } elseif (stripos($k, $prefix) === 0) {
169
                $result[$name][substr($k, $prefixLen)] = implode(', ', $values);
170
            }
171
        }
172
    }
173
 
174
    /**
175
     * Places the status code of the response into the result array.
176
     */
177
    private function extractStatus(
178
        $name,
179
        ResponseInterface $response,
180
        array &$result
181
    ) {
182
        $result[$name] = (int) $response->getStatusCode();
183
    }
184
}