Passed
Pull Request — master (#2)
by
unknown
15:51
created

manifest()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 18
c 0
b 0
f 0
nc 8
nop 1
dl 0
loc 29
rs 8.8333
1
<?php
2
namespace Aws;
3
4
use Psr\Http\Message\RequestInterface;
5
use GuzzleHttp\ClientInterface;
6
use GuzzleHttp\Promise\FulfilledPromise;
7
8
//-----------------------------------------------------------------------------
9
// Functional functions
10
//-----------------------------------------------------------------------------
11
12
/**
13
 * Returns a function that always returns the same value;
14
 *
15
 * @param mixed $value Value to return.
16
 *
17
 * @return callable
18
 */
19
function constantly($value)
20
{
21
    return function () use ($value) { return $value; };
22
}
23
24
/**
25
 * Filters values that do not satisfy the predicate function $pred.
26
 *
27
 * @param mixed    $iterable Iterable sequence of data.
28
 * @param callable $pred Function that accepts a value and returns true/false
29
 *
30
 * @return \Generator
31
 */
32
function filter($iterable, callable $pred)
33
{
34
    foreach ($iterable as $value) {
35
        if ($pred($value)) {
36
            yield $value;
37
        }
38
    }
39
}
40
41
/**
42
 * Applies a map function $f to each value in a collection.
43
 *
44
 * @param mixed    $iterable Iterable sequence of data.
45
 * @param callable $f        Map function to apply.
46
 *
47
 * @return \Generator
48
 */
49
function map($iterable, callable $f)
50
{
51
    foreach ($iterable as $value) {
52
        yield $f($value);
53
    }
54
}
55
56
/**
57
 * Creates a generator that iterates over a sequence, then iterates over each
58
 * value in the sequence and yields the application of the map function to each
59
 * value.
60
 *
61
 * @param mixed    $iterable Iterable sequence of data.
62
 * @param callable $f        Map function to apply.
63
 *
64
 * @return \Generator
65
 */
66
function flatmap($iterable, callable $f)
67
{
68
    foreach (map($iterable, $f) as $outer) {
69
        foreach ($outer as $inner) {
70
            yield $inner;
71
        }
72
    }
73
}
74
75
/**
76
 * Partitions the input sequence into partitions of the specified size.
77
 *
78
 * @param mixed    $iterable Iterable sequence of data.
79
 * @param int $size Size to make each partition (except possibly the last chunk)
80
 *
81
 * @return \Generator
82
 */
83
function partition($iterable, $size)
84
{
85
    $buffer = [];
86
    foreach ($iterable as $value) {
87
        $buffer[] = $value;
88
        if (count($buffer) === $size) {
89
            yield $buffer;
90
            $buffer = [];
91
        }
92
    }
93
94
    if ($buffer) {
95
        yield $buffer;
96
    }
97
}
98
99
/**
100
 * Returns a function that invokes the provided variadic functions one
101
 * after the other until one of the functions returns a non-null value.
102
 * The return function will call each passed function with any arguments it
103
 * is provided.
104
 *
105
 *     $a = function ($x, $y) { return null; };
106
 *     $b = function ($x, $y) { return $x + $y; };
107
 *     $fn = \Aws\or_chain($a, $b);
108
 *     echo $fn(1, 2); // 3
109
 *
110
 * @return callable
111
 */
112
function or_chain()
113
{
114
    $fns = func_get_args();
115
    return function () use ($fns) {
116
        $args = func_get_args();
117
        foreach ($fns as $fn) {
118
            $result = $args ? call_user_func_array($fn, $args) : $fn();
119
            if ($result) {
120
                return $result;
121
            }
122
        }
123
        return null;
124
    };
125
}
126
127
//-----------------------------------------------------------------------------
128
// JSON compiler and loading functions
129
//-----------------------------------------------------------------------------
130
131
/**
132
 * Loads a compiled JSON file from a PHP file.
133
 *
134
 * If the JSON file has not been cached to disk as a PHP file, it will be loaded
135
 * from the JSON source file and returned.
136
 *
137
 * @param string $path Path to the JSON file on disk
138
 *
139
 * @return mixed Returns the JSON decoded data. Note that JSON objects are
140
 *     decoded as associative arrays.
141
 */
142
function load_compiled_json($path)
143
{
144
    if ($compiled = @include("$path.php")) {
145
        return $compiled;
146
    }
147
148
    if (!file_exists($path)) {
149
        throw new \InvalidArgumentException(
150
            sprintf("File not found: %s", $path)
151
        );
152
    }
153
154
    return json_decode(file_get_contents($path), true);
155
}
156
157
/**
158
 * No-op
159
 */
160
function clear_compiled_json()
161
{
162
    // pass
163
}
164
165
//-----------------------------------------------------------------------------
166
// Directory iterator functions.
167
//-----------------------------------------------------------------------------
168
169
/**
170
 * Iterates over the files in a directory and works with custom wrappers.
171
 *
172
 * @param string   $path Path to open (e.g., "s3://foo/bar").
173
 * @param resource $context Stream wrapper context.
174
 *
175
 * @return \Generator Yields relative filename strings.
176
 */
177
function dir_iterator($path, $context = null)
178
{
179
    $dh = $context ? opendir($path, $context) : opendir($path);
0 ignored issues
show
introduced by
$context is of type null|resource, thus it always evaluated to false.
Loading history...
180
    if (!$dh) {
0 ignored issues
show
introduced by
$dh is of type resource, thus it always evaluated to false.
Loading history...
181
        throw new \InvalidArgumentException('File not found: ' . $path);
182
    }
183
    while (($file = readdir($dh)) !== false) {
184
        yield $file;
185
    }
186
    closedir($dh);
187
}
188
189
/**
190
 * Returns a recursive directory iterator that yields absolute filenames.
191
 *
192
 * This iterator is not broken like PHP's built-in DirectoryIterator (which
193
 * will read the first file from a stream wrapper, then rewind, then read
194
 * it again).
195
 *
196
 * @param string   $path    Path to traverse (e.g., s3://bucket/key, /tmp)
197
 * @param resource $context Stream context options.
198
 *
199
 * @return \Generator Yields absolute filenames.
200
 */
201
function recursive_dir_iterator($path, $context = null)
202
{
203
    $invalid = ['.' => true, '..' => true];
204
    $pathLen = strlen($path) + 1;
205
    $iterator = dir_iterator($path, $context);
206
    $queue = [];
207
    do {
208
        while ($iterator->valid()) {
209
            $file = $iterator->current();
210
            $iterator->next();
211
            if (isset($invalid[basename($file)])) {
212
                continue;
213
            }
214
            $fullPath = "{$path}/{$file}";
215
            yield $fullPath;
216
            if (is_dir($fullPath)) {
217
                $queue[] = $iterator;
218
                $iterator = map(
219
                    dir_iterator($fullPath, $context),
220
                    function ($file) use ($fullPath, $pathLen) {
221
                        return substr("{$fullPath}/{$file}", $pathLen);
222
                    }
223
                );
224
                continue;
225
            }
226
        }
227
        $iterator = array_pop($queue);
228
    } while ($iterator);
229
}
230
231
//-----------------------------------------------------------------------------
232
// Misc. functions.
233
//-----------------------------------------------------------------------------
234
235
/**
236
 * Debug function used to describe the provided value type and class.
237
 *
238
 * @param mixed $input
239
 *
240
 * @return string Returns a string containing the type of the variable and
241
 *                if a class is provided, the class name.
242
 */
243
function describe_type($input)
244
{
245
    switch (gettype($input)) {
246
        case 'object':
247
            return 'object(' . get_class($input) . ')';
248
        case 'array':
249
            return 'array(' . count($input) . ')';
250
        default:
251
            ob_start();
252
            var_dump($input);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($input) looks like debug code. Are you sure you do not want to remove it?
Loading history...
253
            // normalize float vs double
254
            return str_replace('double(', 'float(', rtrim(ob_get_clean()));
255
    }
256
}
257
258
/**
259
 * Creates a default HTTP handler based on the available clients.
260
 *
261
 * @return callable
262
 */
263
function default_http_handler()
264
{
265
    $version = (string) ClientInterface::VERSION;
0 ignored issues
show
Deprecated Code introduced by
The constant GuzzleHttp\ClientInterface::VERSION has been deprecated: Will be removed in Guzzle 7.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

265
    $version = (string) /** @scrutinizer ignore-deprecated */ ClientInterface::VERSION;

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
266
    if ($version[0] === '5') {
267
        return new \Aws\Handler\GuzzleV5\GuzzleHandler();
268
    } elseif ($version[0] === '6') {
269
        return new \Aws\Handler\GuzzleV6\GuzzleHandler();
270
    } else {
271
        throw new \RuntimeException('Unknown Guzzle version: ' . $version);
272
    }
273
}
274
275
/**
276
 * Serialize a request for a command but do not send it.
277
 *
278
 * Returns a promise that is fulfilled with the serialized request.
279
 *
280
 * @param CommandInterface $command Command to serialize.
281
 *
282
 * @return RequestInterface
283
 * @throws \RuntimeException
284
 */
285
function serialize(CommandInterface $command)
286
{
287
    $request = null;
288
    $handlerList = $command->getHandlerList();
289
290
    // Return a mock result.
291
    $handlerList->setHandler(
292
        function (CommandInterface $_, RequestInterface $r) use (&$request) {
293
            $request = $r;
294
            return new FulfilledPromise(new Result([]));
295
        }
296
    );
297
298
    call_user_func($handlerList->resolve(), $command)->wait();
299
    if (!$request instanceof RequestInterface) {
300
        throw new \RuntimeException(
301
            'Calling handler did not serialize request'
302
        );
303
    }
304
305
    return $request;
306
}
307
308
/**
309
 * Retrieves data for a service from the SDK's service manifest file.
310
 *
311
 * Manifest data is stored statically, so it does not need to be loaded more
312
 * than once per process. The JSON data is also cached in opcache.
313
 *
314
 * @param string $service Case-insensitive namespace or endpoint prefix of the
315
 *                        service for which you are retrieving manifest data.
316
 *
317
 * @return array
318
 * @throws \InvalidArgumentException if the service is not supported.
319
 */
320
function manifest($service = null)
321
{
322
    // Load the manifest and create aliases for lowercased namespaces
323
    static $manifest = [];
324
    static $aliases = [];
325
    if (empty($manifest)) {
326
        $manifest = load_compiled_json(__DIR__ . '/data/manifest.json');
327
        foreach ($manifest as $endpoint => $info) {
328
            $alias = strtolower($info['namespace']);
329
            if ($alias !== $endpoint) {
330
                $aliases[$alias] = $endpoint;
331
            }
332
        }
333
    }
334
335
    // If no service specified, then return the whole manifest.
336
    if ($service === null) {
337
        return $manifest;
338
    }
339
340
    // Look up the service's info in the manifest data.
341
    $service = strtolower($service);
342
    if (isset($manifest[$service])) {
343
        return $manifest[$service] + ['endpoint' => $service];
344
    } elseif (isset($aliases[$service])) {
345
        return manifest($aliases[$service]);
346
    } else {
347
        throw new \InvalidArgumentException(
348
            "The service \"{$service}\" is not provided by the AWS SDK for PHP."
349
        );
350
    }
351
}
352