Passed
Push — master ( c29e09...6f941d )
by Ryosuke
01:21
created

StreamInterfaceResource::open()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 40
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 20
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 40
ccs 15
cts 15
cp 1
crap 3
rs 9.6
1
<?php
2
3
namespace Mpyw\StreamInterfaceResource;
4
5
use ErrorException;
6
use function GuzzleHttp\Psr7\stream_for;
7
use Iterator;
8
use Psr\Http\Message\StreamInterface;
9
10
class StreamInterfaceResource
11
{
12
    /**
13
     * @param  null|bool|callable|float|int|Iterator|resource|StreamInterface|string $resource
14
     * @param  array                                                                 $options
15
     * @return resource
16
     */
17 45
    public static function open($resource = '', array $options = [])
18
    {
19 45
        $stream = stream_for($resource, $options);
20
21 45
        $wrapper = static::createStreamWrapper($stream);
22 45
        $class = get_class($wrapper);
23 45
        $protocol = sha1($class);
24
25
        set_error_handler(static function (int $code, string $message, string $file, int $line) use (&$error): bool {
26
            // @codeCoverageIgnoreStart
27
            $error = new ErrorException($message, $code, 1, $file, $line);
28
            return true;
29
            // @codeCoverageIgnoreEnd
30 45
        });
31 45
        stream_wrapper_register($protocol, $class);
32 45
        restore_error_handler();
33
34 45
        if ($error) {
35
            // @codeCoverageIgnoreStart
36
            throw $error;
37
            // @codeCoverageIgnoreEnd
38
        }
39
40
        set_error_handler(static function (int $code, string $message, string $file, int $line) use (&$error): bool {
41
            // @codeCoverageIgnoreStart
42
            $error = new ErrorException($message, $code, 1, $file, $line);
43
            return true;
44
            // @codeCoverageIgnoreEnd
45 45
        });
46 45
        $fp = fopen("$protocol://", 'r+b');
47 45
        stream_wrapper_unregister($protocol);
48 45
        restore_error_handler();
49
50 45
        if ($error) {
51
            // @codeCoverageIgnoreStart
52
            throw $error;
53
            // @codeCoverageIgnoreEnd
54
        }
55
56 45
        return $fp;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $fp could also return false which is incompatible with the documented return type resource. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
57
    }
58
59
    protected static function createStreamWrapper(StreamInterface $stream)
60
    {
61
        $wrapper = new class() {
62
            use StreamWrapperTrait;
63
64
            public static $stream;
65
66 45
            protected function stream(): StreamInterface
67
            {
68 45
                return self::$stream;
69
            }
70
        };
71
72
        $wrapper::$stream = $stream;
73
74
        return $wrapper;
75
    }
76
}
77