GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 5cefd1...492078 )
by Anton
04:08
created

Stream   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 233
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 99
c 1
b 0
f 0
dl 0
loc 233
rs 8.96
wmc 43

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __destruct() 0 3 1
A __construct() 0 20 4
A write() 0 15 3
A tell() 0 9 2
A detach() 0 12 2
A eof() 0 3 2
A isSeekable() 0 3 1
A read() 0 7 2
A __get() 0 7 2
A isReadable() 0 3 1
A __toString() 0 7 2
A isWritable() 0 3 1
A getContents() 0 9 2
A getSize() 0 22 5
A close() 0 7 3
A getMetadata() 0 13 6
A rewind() 0 3 1
A seek() 0 7 3

How to fix   Complexity   

Complex Class

Complex classes like Stream often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Stream, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace RingCentral\Psr7;
3
4
use Psr\Http\Message\StreamInterface;
5
6
/**
7
 * PHP stream implementation.
8
 *
9
 * @var $stream
10
 */
11
class Stream implements StreamInterface
12
{
13
    private $stream;
14
    private $size;
15
    private $seekable;
16
    private $readable;
17
    private $writable;
18
    private $uri;
19
    private $customMetadata;
20
21
    /** @var array Hash of readable and writable stream types */
22
    private static $readWriteHash = array(
23
        'read' => array(
24
            'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
25
            'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
26
            'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
27
            'x+t' => true, 'c+t' => true, 'a+' => true
28
        ),
29
        'write' => array(
30
            'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
31
            'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
32
            'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
33
            'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
34
        )
35
    );
36
37
    /**
38
     * This constructor accepts an associative array of options.
39
     *
40
     * - size: (int) If a read stream would otherwise have an indeterminate
41
     *   size, but the size is known due to foreknownledge, then you can
42
     *   provide that size, in bytes.
43
     * - metadata: (array) Any additional metadata to return when the metadata
44
     *   of the stream is accessed.
45
     *
46
     * @param resource $stream  Stream resource to wrap.
47
     * @param array    $options Associative array of options.
48
     *
49
     * @throws \InvalidArgumentException if the stream is not a stream resource
50
     */
51
    public function __construct($stream, $options = array())
52
    {
53
        if (!is_resource($stream)) {
54
            throw new \InvalidArgumentException('Stream must be a resource');
55
        }
56
57
        if (isset($options['size'])) {
58
            $this->size = $options['size'];
59
        }
60
61
        $this->customMetadata = isset($options['metadata'])
62
            ? $options['metadata']
63
            : array();
64
65
        $this->stream = $stream;
66
        $meta = stream_get_meta_data($this->stream);
67
        $this->seekable = $meta['seekable'];
68
        $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
69
        $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
70
        $this->uri = $this->getMetadata('uri');
71
    }
72
73
    public function __get($name)
74
    {
75
        if ($name == 'stream') {
76
            throw new \RuntimeException('The stream is detached');
77
        }
78
79
        throw new \BadMethodCallException('No value for ' . $name);
80
    }
81
82
    /**
83
     * Closes the stream when the destructed
84
     */
85
    public function __destruct()
86
    {
87
        $this->close();
88
    }
89
90
    public function __toString()
91
    {
92
        try {
93
            $this->seek(0);
94
            return (string) stream_get_contents($this->stream);
95
        } catch (\Exception $e) {
96
            return '';
97
        }
98
    }
99
100
    public function getContents()
101
    {
102
        $contents = stream_get_contents($this->stream);
103
104
        if ($contents === false) {
105
            throw new \RuntimeException('Unable to read stream contents');
106
        }
107
108
        return $contents;
109
    }
110
111
    public function close()
112
    {
113
        if (isset($this->stream)) {
114
            if (is_resource($this->stream)) {
115
                fclose($this->stream);
116
            }
117
            $this->detach();
118
        }
119
    }
120
121
    public function detach()
122
    {
123
        if (!isset($this->stream)) {
124
            return null;
125
        }
126
127
        $result = $this->stream;
128
        unset($this->stream);
129
        $this->size = $this->uri = null;
130
        $this->readable = $this->writable = $this->seekable = false;
131
132
        return $result;
133
    }
134
135
    public function getSize()
136
    {
137
        if ($this->size !== null) {
138
            return $this->size;
139
        }
140
141
        if (!isset($this->stream)) {
142
            return null;
143
        }
144
145
        // Clear the stat cache if the stream has a URI
146
        if ($this->uri) {
147
            clearstatcache(true, $this->uri);
148
        }
149
150
        $stats = fstat($this->stream);
151
        if (isset($stats['size'])) {
152
            $this->size = $stats['size'];
153
            return $this->size;
154
        }
155
156
        return null;
157
    }
158
159
    public function isReadable()
160
    {
161
        return $this->readable;
162
    }
163
164
    public function isWritable()
165
    {
166
        return $this->writable;
167
    }
168
169
    public function isSeekable()
170
    {
171
        return $this->seekable;
172
    }
173
174
    public function eof()
175
    {
176
        return !$this->stream || feof($this->stream);
177
    }
178
179
    public function tell()
180
    {
181
        $result = ftell($this->stream);
182
183
        if ($result === false) {
184
            throw new \RuntimeException('Unable to determine stream position');
185
        }
186
187
        return $result;
188
    }
189
190
    public function rewind()
191
    {
192
        $this->seek(0);
193
    }
194
195
    public function seek($offset, $whence = SEEK_SET)
196
    {
197
        if (!$this->seekable) {
198
            throw new \RuntimeException('Stream is not seekable');
199
        } elseif (fseek($this->stream, $offset, $whence) === -1) {
200
            throw new \RuntimeException('Unable to seek to stream position '
201
                . $offset . ' with whence ' . var_export($whence, true));
202
        }
203
    }
204
205
    public function read($length)
206
    {
207
        if (!$this->readable) {
208
            throw new \RuntimeException('Cannot read from non-readable stream');
209
        }
210
211
        return fread($this->stream, $length);
212
    }
213
214
    public function write($string)
215
    {
216
        if (!$this->writable) {
217
            throw new \RuntimeException('Cannot write to a non-writable stream');
218
        }
219
220
        // We can't know the size after writing anything
221
        $this->size = null;
222
        $result = fwrite($this->stream, $string);
223
224
        if ($result === false) {
225
            throw new \RuntimeException('Unable to write to stream');
226
        }
227
228
        return $result;
229
    }
230
231
    public function getMetadata($key = null)
232
    {
233
        if (!isset($this->stream)) {
234
            return $key ? null : array();
235
        } elseif (!$key) {
236
            return $this->customMetadata + stream_get_meta_data($this->stream);
237
        } elseif (isset($this->customMetadata[$key])) {
238
            return $this->customMetadata[$key];
239
        }
240
241
        $meta = stream_get_meta_data($this->stream);
242
243
        return isset($meta[$key]) ? $meta[$key] : null;
244
    }
245
}
246