Stream::getContents()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
namespace kalanis\RemoteRequestPsr\Content;
4
5
6
use kalanis\RemoteRequest\RequestException;
7
use Psr\Http\Message\StreamInterface;
8
use RuntimeException;
9
10
11
/**
12
 * Class Address
13
 * @package kalanis\RemoteRequestPsr\Content
14
 * Simple implementation of URI interface as address
15
 *
16
 * @todo: note: for immutability it might need a pair of classes
17
 *      - one for immutability with interface and other with stored data; but not now
18
 */
19
class Stream implements StreamInterface
20
{
21
    /** @var resource|null */
22
    protected $localStream = null;
23
    protected int $offset = 0;
24
25
    /**
26
     * @param resource|string|int|float|null $source
27
     * @throws RequestException
28
     */
29 17
    public function __construct($source)
30
    {
31 17
        $this->localStream = is_resource($source) ? $source : $this->toStream($source);
32 17
    }
33
34
    /**
35
     * @param string|int|float|null $content
36
     * @throws RequestException
37
     * @return resource
38
     */
39 13
    protected function toStream($content)
40
    {
41 13
        $stream = fopen('php://temp', 'rb+');
42 13
        if (false === $stream) {
43
            // @codeCoverageIgnoreStart
44
            throw new RequestException('Problem with php internals');
45
        }
46
        // @codeCoverageIgnoreEnd
47 13
        fwrite($stream, strval($content));
48 13
        return $stream;
49
    }
50
51 3
    public function __toString(): string
52
    {
53
        try {
54 3
            return strval(stream_get_contents($this->getLocalStream(), -1, 0));
55 1
        } catch (RuntimeException $ex) {
56 1
            return '';
57
        }
58
    }
59
60 5
    public function close(): void
61
    {
62
        try {
63 5
            fclose($this->getLocalStream());
64 5
            $this->localStream = null;
65 5
            $this->offset = 0;
66 1
        } catch (RuntimeException $ex) {
67
            // nothing to do
68
        }
69 5
    }
70
71 3
    public function detach()
72
    {
73 3
        $stream = $this->localStream;
74 3
        $this->localStream = null;
75 3
        $this->offset = 0;
76 3
        return $stream;
77
    }
78
79 1
    public function getSize(): ?int
80
    {
81
        try {
82 1
            $data = fstat($this->getLocalStream());
83 1
            return (false !== $data) ? $data['size'] : null;
84 1
        } catch (RuntimeException $ex) {
85 1
            return null;
86
        }
87
    }
88
89 6
    public function tell(): int
90
    {
91 6
        return intval(ftell($this->getLocalStream()));
92
    }
93
94 5
    public function eof(): bool
95
    {
96 5
        return feof($this->getLocalStream());
97
    }
98
99 2
    public function isSeekable(): bool
100
    {
101 2
        $meta = stream_get_meta_data($this->getLocalStream());
102 2
        return $meta['seekable'];
103
    }
104
105 6
    public function seek(int $offset, int $whence = SEEK_SET): void
106
    {
107 6
        fseek($this->getLocalStream(), $offset, $whence);
108 6
        $this->offset = $this->tell();
109 6
    }
110
111 6
    public function rewind(): void
112
    {
113 6
        $this->seek(0);
114 6
    }
115
116 1
    public function isWritable(): bool
117
    {
118 1
        $meta = stream_get_meta_data($this->getLocalStream());
119
        return (
120 1
            (false !== stripos($meta['mode'], 'w'))
121
            || (false !== stripos($meta['mode'], 'a'))
122
            || (false !== stripos($meta['mode'], 'x'))
123 1
            || (false !== stripos($meta['mode'], 'c'))
124
        );
125
    }
126
127 1
    public function write(string $string): int
128
    {
129 1
        return intval(fwrite($this->getLocalStream(), $string));
130
    }
131
132 2
    public function isReadable(): bool
133
    {
134 2
        $meta = stream_get_meta_data($this->getLocalStream());
135
        return (
136 2
            (false !== stripos($meta['mode'], 'r'))
137 2
            || (false !== stripos($meta['mode'], '+'))
138
        );
139
    }
140
141 7
    public function read(int $length): string
142
    {
143 7
        $data = strval(stream_get_contents($this->getLocalStream(), $length, $this->offset));
144 6
        $this->offset += strlen($data);
145 6
        return $data;
146
    }
147
148 4
    public function getContents(): string
149
    {
150 4
        $data = strval(stream_get_contents($this->getLocalStream(), -1, $this->offset));
151 3
        $this->offset += strlen($data);
152 3
        return $data;
153
    }
154
155 1
    public function getMetadata(?string $key = null)
156
    {
157
        try {
158 1
            $data = stream_get_meta_data($this->getLocalStream());
159 1
            if (!is_null($key)) {
160 1
                return (isset($data[$key])) ? $data[$key] : null;
161
            } else {
162 1
                return $data;
163
            }
164 1
        } catch (RuntimeException $ex) {
165 1
            return null;
166
        }
167
    }
168
169
    /**
170
     * @throws RuntimeException
171
     * @return resource
172
     */
173 15
    protected function getLocalStream()
174
    {
175 15
        if (empty($this->localStream)) {
176 7
            throw new RuntimeException('No stream available!');
177
        }
178 12
        return $this->localStream;
179
    }
180
}
181