Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws;
3
 
4
use GuzzleHttp\Client;
5
use Psr\Http\Message\RequestInterface;
6
use GuzzleHttp\ClientInterface;
7
use GuzzleHttp\Promise\FulfilledPromise;
8
 
9
//-----------------------------------------------------------------------------
10
// Functional functions
11
//-----------------------------------------------------------------------------
12
 
13
/**
14
 * Returns a function that always returns the same value;
15
 *
16
 * @param mixed $value Value to return.
17
 *
18
 * @return callable
19
 */
20
function constantly($value)
21
{
22
    return function () use ($value) { return $value; };
23
}
24
 
25
/**
26
 * Filters values that do not satisfy the predicate function $pred.
27
 *
28
 * @param mixed    $iterable Iterable sequence of data.
29
 * @param callable $pred Function that accepts a value and returns true/false
30
 *
31
 * @return \Generator
32
 */
33
function filter($iterable, callable $pred)
34
{
35
    foreach ($iterable as $value) {
36
        if ($pred($value)) {
37
            yield $value;
38
        }
39
    }
40
}
41
 
42
/**
43
 * Applies a map function $f to each value in a collection.
44
 *
45
 * @param mixed    $iterable Iterable sequence of data.
46
 * @param callable $f        Map function to apply.
47
 *
48
 * @return \Generator
49
 */
50
function map($iterable, callable $f)
51
{
52
    foreach ($iterable as $value) {
53
        yield $f($value);
54
    }
55
}
56
 
57
/**
58
 * Creates a generator that iterates over a sequence, then iterates over each
59
 * value in the sequence and yields the application of the map function to each
60
 * value.
61
 *
62
 * @param mixed    $iterable Iterable sequence of data.
63
 * @param callable $f        Map function to apply.
64
 *
65
 * @return \Generator
66
 */
67
function flatmap($iterable, callable $f)
68
{
69
    foreach (map($iterable, $f) as $outer) {
70
        foreach ($outer as $inner) {
71
            yield $inner;
72
        }
73
    }
74
}
75
 
76
/**
77
 * Partitions the input sequence into partitions of the specified size.
78
 *
79
 * @param mixed    $iterable Iterable sequence of data.
80
 * @param int $size Size to make each partition (except possibly the last chunk)
81
 *
82
 * @return \Generator
83
 */
84
function partition($iterable, $size)
85
{
86
    $buffer = [];
87
    foreach ($iterable as $value) {
88
        $buffer[] = $value;
89
        if (count($buffer) === $size) {
90
            yield $buffer;
91
            $buffer = [];
92
        }
93
    }
94
 
95
    if ($buffer) {
96
        yield $buffer;
97
    }
98
}
99
 
100
/**
101
 * Returns a function that invokes the provided variadic functions one
102
 * after the other until one of the functions returns a non-null value.
103
 * The return function will call each passed function with any arguments it
104
 * is provided.
105
 *
106
 *     $a = function ($x, $y) { return null; };
107
 *     $b = function ($x, $y) { return $x + $y; };
108
 *     $fn = \Aws\or_chain($a, $b);
109
 *     echo $fn(1, 2); // 3
110
 *
111
 * @return callable
112
 */
113
function or_chain()
114
{
115
    $fns = func_get_args();
116
    return function () use ($fns) {
117
        $args = func_get_args();
118
        foreach ($fns as $fn) {
119
            $result = $args ? call_user_func_array($fn, $args) : $fn();
120
            if ($result) {
121
                return $result;
122
            }
123
        }
124
        return null;
125
    };
126
}
127
 
128
//-----------------------------------------------------------------------------
129
// JSON compiler and loading functions
130
//-----------------------------------------------------------------------------
131
 
132
/**
133
 * Loads a compiled JSON file from a PHP file.
134
 *
135
 * If the JSON file has not been cached to disk as a PHP file, it will be loaded
136
 * from the JSON source file and returned.
137
 *
138
 * @param string $path Path to the JSON file on disk
139
 *
140
 * @return mixed Returns the JSON decoded data. Note that JSON objects are
141
 *     decoded as associative arrays.
142
 */
143
function load_compiled_json($path)
144
{
145
    static $compiledList = [];
146
 
147
    $compiledFilepath = "{$path}.php";
148
 
149
    if (!isset($compiledList[$compiledFilepath])) {
150
        if (is_readable($compiledFilepath)) {
151
            $compiledList[$compiledFilepath] = include($compiledFilepath);
152
        }
153
    }
154
 
155
    if (isset($compiledList[$compiledFilepath])) {
156
        return $compiledList[$compiledFilepath];
157
    }
158
 
159
    if (!file_exists($path)) {
160
        throw new \InvalidArgumentException(
161
            sprintf("File not found: %s", $path)
162
        );
163
    }
164
 
165
    return json_decode(file_get_contents($path), true);
166
}
167
 
168
/**
169
 * No-op
170
 */
171
function clear_compiled_json()
172
{
173
    // pass
174
}
175
 
176
//-----------------------------------------------------------------------------
177
// Directory iterator functions.
178
//-----------------------------------------------------------------------------
179
 
180
/**
181
 * Iterates over the files in a directory and works with custom wrappers.
182
 *
183
 * @param string   $path Path to open (e.g., "s3://foo/bar").
184
 * @param resource $context Stream wrapper context.
185
 *
186
 * @return \Generator Yields relative filename strings.
187
 */
188
function dir_iterator($path, $context = null)
189
{
190
    $dh = $context ? opendir($path, $context) : opendir($path);
191
    if (!$dh) {
192
        throw new \InvalidArgumentException('File not found: ' . $path);
193
    }
194
    while (($file = readdir($dh)) !== false) {
195
        yield $file;
196
    }
197
    closedir($dh);
198
}
199
 
200
/**
201
 * Returns a recursive directory iterator that yields absolute filenames.
202
 *
203
 * This iterator is not broken like PHP's built-in DirectoryIterator (which
204
 * will read the first file from a stream wrapper, then rewind, then read
205
 * it again).
206
 *
207
 * @param string   $path    Path to traverse (e.g., s3://bucket/key, /tmp)
208
 * @param resource $context Stream context options.
209
 *
210
 * @return \Generator Yields absolute filenames.
211
 */
212
function recursive_dir_iterator($path, $context = null)
213
{
214
    $invalid = ['.' => true, '..' => true];
215
    $pathLen = strlen($path) + 1;
216
    $iterator = dir_iterator($path, $context);
217
    $queue = [];
218
    do {
219
        while ($iterator->valid()) {
220
            $file = $iterator->current();
221
            $iterator->next();
222
            if (isset($invalid[basename($file)])) {
223
                continue;
224
            }
225
            $fullPath = "{$path}/{$file}";
226
            yield $fullPath;
227
            if (is_dir($fullPath)) {
228
                $queue[] = $iterator;
229
                $iterator = map(
230
                    dir_iterator($fullPath, $context),
231
                    function ($file) use ($fullPath, $pathLen) {
232
                        return substr("{$fullPath}/{$file}", $pathLen);
233
                    }
234
                );
235
                continue;
236
            }
237
        }
238
        $iterator = array_pop($queue);
239
    } while ($iterator);
240
}
241
 
242
//-----------------------------------------------------------------------------
243
// Misc. functions.
244
//-----------------------------------------------------------------------------
245
 
246
/**
247
 * Debug function used to describe the provided value type and class.
248
 *
249
 * @param mixed $input
250
 *
251
 * @return string Returns a string containing the type of the variable and
252
 *                if a class is provided, the class name.
253
 */
254
function describe_type($input)
255
{
256
    switch (gettype($input)) {
257
        case 'object':
258
            return 'object(' . get_class($input) . ')';
259
        case 'array':
260
            return 'array(' . count($input) . ')';
261
        default:
262
            ob_start();
263
            var_dump($input);
264
            // normalize float vs double
265
            return str_replace('double(', 'float(', rtrim(ob_get_clean()));
266
    }
267
}
268
 
269
/**
270
 * Creates a default HTTP handler based on the available clients.
271
 *
272
 * @return callable
273
 */
274
function default_http_handler()
275
{
276
    $version = guzzle_major_version();
277
    // If Guzzle 6 or 7 installed
278
    if ($version === 6 || $version === 7) {
279
        return new \Aws\Handler\GuzzleV6\GuzzleHandler();
280
    }
281
 
282
    // If Guzzle 5 installed
283
    if ($version === 5) {
284
        return new \Aws\Handler\GuzzleV5\GuzzleHandler();
285
    }
286
 
287
    throw new \RuntimeException('Unknown Guzzle version: ' . $version);
288
}
289
 
290
/**
291
 * Gets the default user agent string depending on the Guzzle version
292
 *
293
 * @return string
294
 */
295
function default_user_agent()
296
{
297
    $version = guzzle_major_version();
298
    // If Guzzle 6 or 7 installed
299
    if ($version === 6 || $version === 7) {
300
        return \GuzzleHttp\default_user_agent();
301
    }
302
 
303
    // If Guzzle 5 installed
304
    if ($version === 5) {
305
        return \GuzzleHttp\Client::getDefaultUserAgent();
306
    }
307
 
308
    throw new \RuntimeException('Unknown Guzzle version: ' . $version);
309
}
310
 
311
/**
312
 * Get the major version of guzzle that is installed.
313
 *
314
 * @internal This function is internal and should not be used outside aws/aws-sdk-php.
315
 * @return int
316
 * @throws \RuntimeException
317
 */
318
function guzzle_major_version()
319
{
320
    static $cache = null;
321
    if (null !== $cache) {
322
        return $cache;
323
    }
324
 
325
    if (defined('\GuzzleHttp\ClientInterface::VERSION')) {
326
        $version = (string) ClientInterface::VERSION;
327
        if ($version[0] === '6') {
328
            return $cache = 6;
329
        }
330
        if ($version[0] === '5') {
331
            return $cache = 5;
332
        }
333
    } elseif (defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION')) {
334
        return $cache = ClientInterface::MAJOR_VERSION;
335
    }
336
 
337
    throw new \RuntimeException('Unable to determine what Guzzle version is installed.');
338
}
339
 
340
/**
341
 * Serialize a request for a command but do not send it.
342
 *
343
 * Returns a promise that is fulfilled with the serialized request.
344
 *
345
 * @param CommandInterface $command Command to serialize.
346
 *
347
 * @return RequestInterface
348
 * @throws \RuntimeException
349
 */
350
function serialize(CommandInterface $command)
351
{
352
    $request = null;
353
    $handlerList = $command->getHandlerList();
354
 
355
    // Return a mock result.
356
    $handlerList->setHandler(
357
        function (CommandInterface $_, RequestInterface $r) use (&$request) {
358
            $request = $r;
359
            return new FulfilledPromise(new Result([]));
360
        }
361
    );
362
 
363
    call_user_func($handlerList->resolve(), $command)->wait();
364
    if (!$request instanceof RequestInterface) {
365
        throw new \RuntimeException(
366
            'Calling handler did not serialize request'
367
        );
368
    }
369
 
370
    return $request;
371
}
372
 
373
/**
374
 * Retrieves data for a service from the SDK's service manifest file.
375
 *
376
 * Manifest data is stored statically, so it does not need to be loaded more
377
 * than once per process. The JSON data is also cached in opcache.
378
 *
379
 * @param string $service Case-insensitive namespace or endpoint prefix of the
380
 *                        service for which you are retrieving manifest data.
381
 *
382
 * @return array
383
 * @throws \InvalidArgumentException if the service is not supported.
384
 */
385
function manifest($service = null)
386
{
387
    // Load the manifest and create aliases for lowercased namespaces
388
    static $manifest = [];
389
    static $aliases = [];
390
    if (empty($manifest)) {
391
        $manifest = load_compiled_json(__DIR__ . '/data/manifest.json');
392
        foreach ($manifest as $endpoint => $info) {
393
            $alias = strtolower($info['namespace']);
394
            if ($alias !== $endpoint) {
395
                $aliases[$alias] = $endpoint;
396
            }
397
        }
398
    }
399
 
400
    // If no service specified, then return the whole manifest.
401
    if ($service === null) {
402
        return $manifest;
403
    }
404
 
405
    // Look up the service's info in the manifest data.
406
    $service = strtolower($service);
407
    if (isset($manifest[$service])) {
408
        return $manifest[$service] + ['endpoint' => $service];
409
    }
410
 
411
    if (isset($aliases[$service])) {
412
        return manifest($aliases[$service]);
413
    }
414
 
415
    throw new \InvalidArgumentException(
416
        "The service \"{$service}\" is not provided by the AWS SDK for PHP."
417
    );
418
}
419
 
420
/**
421
 * Checks if supplied parameter is a valid hostname
422
 *
423
 * @param string $hostname
424
 * @return bool
425
 */
426
function is_valid_hostname($hostname)
427
{
428
    return (
429
        preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*\.?$/i", $hostname)
430
        && preg_match("/^.{1,253}$/", $hostname)
431
        && preg_match("/^[^\.]{1,63}(\.[^\.]{0,63})*$/", $hostname)
432
    );
433
}
434
 
435
/**
436
 * Checks if supplied parameter is a valid host label
437
 *
438
 * @param $label
439
 * @return bool
440
 */
441
function is_valid_hostlabel($label)
442
{
443
    return preg_match("/^(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$/", $label);
444
}
445
 
446
/**
447
 * Ignores '#' full line comments, which parse_ini_file no longer does
448
 * in PHP 7+.
449
 *
450
 * @param $filename
451
 * @param bool $process_sections
452
 * @param int $scanner_mode
453
 * @return array|bool
454
 */
455
function parse_ini_file(
456
    $filename,
457
    $process_sections = false,
458
    $scanner_mode = INI_SCANNER_NORMAL)
459
{
460
    return parse_ini_string(
461
        preg_replace('/^#.*\\n/m', "", file_get_contents($filename)),
462
        $process_sections,
463
        $scanner_mode
464
    );
465
}
466
 
467
/**
468
 * Outputs boolean value of input for a select range of possible values,
469
 * null otherwise
470
 *
471
 * @param $input
472
 * @return bool|null
473
 */
474
function boolean_value($input)
475
{
476
    if (is_bool($input)) {
477
        return $input;
478
    }
479
 
480
    if ($input === 0) {
481
        return false;
482
    }
483
 
484
    if ($input === 1) {
485
        return true;
486
    }
487
 
488
    if (is_string($input)) {
489
        switch (strtolower($input)) {
490
            case "true":
491
            case "on":
492
            case "1":
493
                return true;
494
                break;
495
 
496
            case "false":
497
            case "off":
498
            case "0":
499
                return false;
500
                break;
501
        }
502
    }
503
    return null;
504
}
505
 
506
/**
507
 * Checks if an input is a valid epoch time
508
 *
509
 * @param $input
510
 * @return bool
511
 */
512
function is_valid_epoch($input)
513
{
514
    if (is_string($input) || is_numeric($input)) {
515
        if (is_string($input) && !preg_match("/^-?[0-9]+\.?[0-9]*$/", $input)) {
516
            return false;
517
        }
518
        return true;
519
    }
520
    return false;
521
}
522
 
523
/**
524
 * Checks if an input is a fips pseudo region
525
 *
526
 * @param $region
527
 * @return bool
528
 */
529
function is_fips_pseudo_region($region)
530
{
531
    return strpos($region, 'fips-') !== false || strpos($region, '-fips') !== false;
532
}
533
 
534
/**
535
 * Returns a region without a fips label
536
 *
537
 * @param $region
538
 * @return string
539
 */
540
function strip_fips_pseudo_regions($region)
541
{
542
    return str_replace(['fips-', '-fips'], ['', ''], $region);
543
}
544