Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | 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
{
1441 ariadna 276
    return new \Aws\Handler\GuzzleV6\GuzzleHandler();
1 efrain 277
}
278
 
279
/**
280
 * Gets the default user agent string depending on the Guzzle version
281
 *
282
 * @return string
283
 */
284
function default_user_agent()
285
{
1441 ariadna 286
    return \GuzzleHttp\default_user_agent();
1 efrain 287
}
288
 
289
/**
290
 * Serialize a request for a command but do not send it.
291
 *
292
 * Returns a promise that is fulfilled with the serialized request.
293
 *
294
 * @param CommandInterface $command Command to serialize.
295
 *
296
 * @return RequestInterface
297
 * @throws \RuntimeException
298
 */
299
function serialize(CommandInterface $command)
300
{
301
    $request = null;
302
    $handlerList = $command->getHandlerList();
303
 
304
    // Return a mock result.
305
    $handlerList->setHandler(
306
        function (CommandInterface $_, RequestInterface $r) use (&$request) {
307
            $request = $r;
308
            return new FulfilledPromise(new Result([]));
309
        }
310
    );
311
 
312
    call_user_func($handlerList->resolve(), $command)->wait();
313
    if (!$request instanceof RequestInterface) {
314
        throw new \RuntimeException(
315
            'Calling handler did not serialize request'
316
        );
317
    }
318
 
319
    return $request;
320
}
321
 
322
/**
323
 * Retrieves data for a service from the SDK's service manifest file.
324
 *
325
 * Manifest data is stored statically, so it does not need to be loaded more
326
 * than once per process. The JSON data is also cached in opcache.
327
 *
328
 * @param string $service Case-insensitive namespace or endpoint prefix of the
329
 *                        service for which you are retrieving manifest data.
330
 *
331
 * @return array
332
 * @throws \InvalidArgumentException if the service is not supported.
333
 */
334
function manifest($service = null)
335
{
336
    // Load the manifest and create aliases for lowercased namespaces
337
    static $manifest = [];
338
    static $aliases = [];
339
    if (empty($manifest)) {
340
        $manifest = load_compiled_json(__DIR__ . '/data/manifest.json');
341
        foreach ($manifest as $endpoint => $info) {
342
            $alias = strtolower($info['namespace']);
343
            if ($alias !== $endpoint) {
344
                $aliases[$alias] = $endpoint;
345
            }
346
        }
347
    }
348
 
349
    // If no service specified, then return the whole manifest.
350
    if ($service === null) {
351
        return $manifest;
352
    }
353
 
354
    // Look up the service's info in the manifest data.
355
    $service = strtolower($service);
356
    if (isset($manifest[$service])) {
357
        return $manifest[$service] + ['endpoint' => $service];
358
    }
359
 
360
    if (isset($aliases[$service])) {
361
        return manifest($aliases[$service]);
362
    }
363
 
364
    throw new \InvalidArgumentException(
365
        "The service \"{$service}\" is not provided by the AWS SDK for PHP."
366
    );
367
}
368
 
369
/**
370
 * Checks if supplied parameter is a valid hostname
371
 *
372
 * @param string $hostname
373
 * @return bool
374
 */
375
function is_valid_hostname($hostname)
376
{
377
    return (
378
        preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*\.?$/i", $hostname)
379
        && preg_match("/^.{1,253}$/", $hostname)
380
        && preg_match("/^[^\.]{1,63}(\.[^\.]{0,63})*$/", $hostname)
381
    );
382
}
383
 
384
/**
385
 * Checks if supplied parameter is a valid host label
386
 *
387
 * @param $label
388
 * @return bool
389
 */
390
function is_valid_hostlabel($label)
391
{
392
    return preg_match("/^(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$/", $label);
393
}
394
 
395
/**
396
 * Ignores '#' full line comments, which parse_ini_file no longer does
397
 * in PHP 7+.
398
 *
399
 * @param $filename
400
 * @param bool $process_sections
401
 * @param int $scanner_mode
402
 * @return array|bool
403
 */
404
function parse_ini_file(
405
    $filename,
406
    $process_sections = false,
407
    $scanner_mode = INI_SCANNER_NORMAL)
408
{
409
    return parse_ini_string(
410
        preg_replace('/^#.*\\n/m', "", file_get_contents($filename)),
411
        $process_sections,
412
        $scanner_mode
413
    );
414
}
415
 
416
/**
417
 * Outputs boolean value of input for a select range of possible values,
418
 * null otherwise
419
 *
420
 * @param $input
421
 * @return bool|null
422
 */
423
function boolean_value($input)
424
{
425
    if (is_bool($input)) {
426
        return $input;
427
    }
428
 
429
    if ($input === 0) {
430
        return false;
431
    }
432
 
433
    if ($input === 1) {
434
        return true;
435
    }
436
 
437
    if (is_string($input)) {
438
        switch (strtolower($input)) {
439
            case "true":
440
            case "on":
441
            case "1":
442
                return true;
443
                break;
444
 
445
            case "false":
446
            case "off":
447
            case "0":
448
                return false;
449
                break;
450
        }
451
    }
452
    return null;
453
}
454
 
455
/**
1441 ariadna 456
 * Parses ini sections with subsections (i.e. the service section)
457
 *
458
 * @param $filename
459
 * @param $filename
460
 * @return array
461
 */
462
function parse_ini_section_with_subsections($filename, $section_name) {
463
    $config = [];
464
    $stream = fopen($filename, 'r');
465
 
466
    if (!$stream) {
467
        return $config;
468
    }
469
 
470
    $current_subsection = '';
471
 
472
    while (!feof($stream)) {
473
        $line = trim(fgets($stream));
474
 
475
        if (empty($line) || in_array($line[0], [';', '#'])) {
476
            continue;
477
        }
478
 
479
        if (preg_match('/^\[.*\]$/', $line)
480
            && trim($line, '[]') === $section_name)
481
        {
482
            while (!feof($stream)) {
483
                $line = trim(fgets($stream));
484
 
485
                if (empty($line) || in_array($line[0], [';', '#'])) {
486
                    continue;
487
                }
488
 
489
                if (preg_match('/^\[.*\]$/', $line)
490
                    && trim($line, '[]') === $section_name)
491
                {
492
                    continue;
493
                } elseif (strpos($line, '[') === 0) {
494
                    break;
495
                }
496
 
497
                if (strpos($line, ' = ') !== false) {
498
                    list($key, $value) = explode(' = ', $line, 2);
499
                    if (empty($current_subsection)) {
500
                        $config[$key] = $value;
501
                    } else {
502
                        $config[$current_subsection][$key] = $value;
503
                    }
504
                } else {
505
                    $current_subsection = trim(str_replace('=', '', $line));
506
                    $config[$current_subsection] = [];
507
                }
508
            }
509
        }
510
    }
511
 
512
    fclose($stream);
513
    return $config;
514
}
515
 
516
/**
1 efrain 517
 * Checks if an input is a valid epoch time
518
 *
519
 * @param $input
520
 * @return bool
521
 */
522
function is_valid_epoch($input)
523
{
524
    if (is_string($input) || is_numeric($input)) {
525
        if (is_string($input) && !preg_match("/^-?[0-9]+\.?[0-9]*$/", $input)) {
526
            return false;
527
        }
528
        return true;
529
    }
530
    return false;
531
}
532
 
533
/**
534
 * Checks if an input is a fips pseudo region
535
 *
536
 * @param $region
537
 * @return bool
538
 */
539
function is_fips_pseudo_region($region)
540
{
541
    return strpos($region, 'fips-') !== false || strpos($region, '-fips') !== false;
542
}
543
 
544
/**
545
 * Returns a region without a fips label
546
 *
547
 * @param $region
548
 * @return string
549
 */
550
function strip_fips_pseudo_regions($region)
551
{
552
    return str_replace(['fips-', '-fips'], ['', ''], $region);
553
}
554
 
1441 ariadna 555
/**
556
 * Checks if an array is associative
557
 *
558
 * @param array $array
559
 *
560
 * @return bool
561
 */
562
function is_associative(array $array): bool
563
{
564
    if (empty($array)) {
565
        return false;
566
    }
567
 
568
    if (function_exists('array_is_list')) {
569
        return !array_is_list($array);
570
    }
571
 
572
    return array_keys($array) !== range(0, count($array) - 1);
573
}
574