Completed
Push — develop ( 86312e...86b985 )
by Andrea Marco
04:47
created

DataStreaming::streamResource()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Cerbero\JsonObjects;
4
5
use Psr\Http\Message\MessageInterface;
6
use Psr\Http\Message\StreamInterface;
7
8
/**
9
 * The data streaming.
10
 *
11
 */
12
class DataStreaming
13
{
14
    /**
15
     * Stream content from the given data.
16
     *
17
     * @param mixed $data
18
     * @return resource
19
     *
20
     * @throws JsonObjectsException
21
     */
22 35
    public function streamData($data)
23
    {
24 35
        $method = 'stream' . ucfirst(gettype($data));
25
26 35
        if (method_exists($this, $method)) {
27 29
            return $this->{$method}($data);
28
        }
29
30 6
        throw new JsonObjectsException('Unable to create a stream from the given data.');
31
    }
32
33
    /**
34
     * Stream content from the given resource
35
     *
36
     * @param mixed $resource
37
     * @return resource
38
     *
39
     * @throws JsonObjectsException
40
     */
41 10
    public function streamResource($resource)
42
    {
43 10
        if (is_resource($resource)) {
44 7
            return $resource;
45
        }
46
47 3
        throw new JsonObjectsException('Unable to create a stream from an invalid resource.');
48
    }
49
50
    /**
51
     * Stream content from the given string
52
     *
53
     * @param string $string
54
     * @return resource
55
     *
56
     * @throws JsonObjectsException
57
     */
58 31
    public function streamString(string $string)
59
    {
60 31
        $stream = extension_loaded('zlib') ? @gzopen($string, 'rb') : @fopen($string, 'rb');
61
62 31
        if ($stream === false) {
63 3
            throw new JsonObjectsException("Failed to open stream from: {$string}");
64
        }
65
66 28
        return $stream;
67
    }
68
69
    /**
70
     * Stream content from the given object
71
     *
72
     * @param object $object
73
     * @return resource
74
     *
75
     * @throws JsonObjectsException
76
     */
77 10
    public function streamObject(object $object)
78
    {
79 10
        if ($object instanceof MessageInterface) {
80 2
            $object = $object->getBody();
81
        }
82
83 10
        if ($object instanceof StreamInterface) {
84 8
            return $this->streamWrapper($object);
85
        }
86
87 2
        throw new JsonObjectsException('Unable to create a stream from ' . get_class($object));
88
    }
89
90
    /**
91
     * Stream content from the given stream wrapper
92
     *
93
     * @param \Psr\Http\Message\StreamInterface $stream
94
     * @return resource
95
     *
96
     * @throws JsonObjectsException
97
     */
98 8
    public function streamWrapper(StreamInterface $stream)
99
    {
100
        // Register this class as stream wrapper if not already registered
101 8
        if (!in_array('cerbero-json-objects', stream_get_wrappers())) {
102 2
            stream_wrapper_register('cerbero-json-objects', static::class);
103
        }
104
105 8
        $mode = $this->getModeByStream($stream);
106
107
        // Retrieve a handler of the opened stream
108 6
        $resource = @fopen('cerbero-json-objects://stream', $mode, false, stream_context_create([
109 6
            'cerbero-json-objects' => compact('stream'),
110
        ]));
111
112 6
        if ($resource === false) {
113 6
            throw new JsonObjectsException('Failed to open stream from the given stream wrapper.');
114
        }
115
116
        return $resource;
117
    }
118
119
    /**
120
     * Retrieve the mode to open the given stream
121
     *
122
     * @param \Psr\Http\Message\StreamInterface $stream
123
     * @return string
124
     *
125
     * @throws JsonObjectsException
126
     */
127 8
    private function getModeByStream(StreamInterface $stream) : string
128
    {
129 8
        if ($stream->isReadable()) {
130 6
            return $stream->isWritable() ? 'r+b' : 'rb';
131
        }
132
133 2
        if ($stream->isWritable()) {
134
            return 'wb';
135
        }
136
137 2
        throw new JsonObjectsException('The stream is not readable or writable.');
138
    }
139
}
140