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.
Completed
Push — master ( b355e3...8f7b2d )
by Patrique
01:15
created

Stream   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 238
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 49
lcom 1
cbo 0
dl 0
loc 238
rs 8.48
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 3
A __toString() 0 4 1
A close() 0 6 2
A detach() 0 7 1
A getSize() 0 13 4
A tell() 0 11 3
A eof() 0 4 2
A isSeekable() 0 15 3
A seek() 0 6 4
A rewind() 0 6 4
A isWritable() 0 15 4
A write() 0 14 4
A isReadable() 0 15 4
A read() 0 14 4
A getContents() 0 10 3
A getMetadata() 0 14 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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
3
declare(strict_types=1);
4
5
namespace Patoui\Router;
6
7
use InvalidArgumentException;
8
use Psr\Http\Message\StreamInterface;
9
use RuntimeException;
10
11
class Stream implements StreamInterface
12
{
13
    public const TEMPORARY_STREAM = 'php://temp';
14
15
    /** @var null|resource */
16
    private $stream;
17
18
    /**
19
     * Stream constructor.
20
     * @param resource $stream
21
     */
22
    public function __construct($stream)
23
    {
24
        /**
25
         * @psalm-suppress DocblockTypeContradiction
26
         * @psalm-suppress RedundantConditionGivenDocblockType
27
         */
28
        if ($stream !== null && ! is_resource($stream)) {
29
            throw new InvalidArgumentException('Invalid resource provided.');
30
        }
31
32
        $this->stream = $stream;
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function __toString()
39
    {
40
        return $this->getContents();
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function close(): void
47
    {
48
        if (is_resource($this->stream)) {
49
            fclose($this->stream);
50
        }
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function detach()
57
    {
58
        $stream = $this->stream;
59
        $this->stream = null;
60
61
        return $stream;
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function getSize(): ?int
68
    {
69
        if ($this->stream) {
70
            $stats = fstat($this->stream);
71
            if (is_array($stats)) {
72
                /** @var mixed $size */
73
                $size = $stats['size'] ?? null;
74
                return $size !== null ? (int) $size : null;
75
            }
76
        }
77
78
        return null;
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function tell(): int
85
    {
86
        if ($this->stream) {
87
            $position = ftell($this->stream);
88
            if ($position !== false) {
89
                return $position;
90
            }
91
        }
92
93
        throw new RuntimeException('Unable to find position of the current position of the file read/write pointer');
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function eof(): bool
100
    {
101
        return $this->stream ? feof($this->stream) : true;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function isSeekable(): bool
108
    {
109
        if (!$this->stream) {
110
            return false;
111
        }
112
113
        /** @var mixed $seekable */
114
        $seekable = $this->getMetadata('seekable');
115
116
        if (! is_bool($seekable)) {
117
            return false;
118
        }
119
120
        return $seekable;
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126
    public function seek($offset, $whence = SEEK_SET): void
127
    {
128
        if (! $this->isSeekable() || ($this->stream && fseek($this->stream, $offset, $whence) === -1)) {
129
            throw new RuntimeException('Unable to seek stream/resource');
130
        }
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function rewind(): void
137
    {
138
        if (! $this->isSeekable() || ($this->stream && rewind($this->stream) === false)) {
139
            throw new RuntimeException('Unable to rewind stream/resource');
140
        }
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function isWritable(): bool
147
    {
148
        if (! $this->stream) {
149
            return false;
150
        }
151
152
        /** @var mixed $mode */
153
        $mode = $this->getMetadata('mode');
154
155
        if (! is_string($mode)) {
156
            return false;
157
        }
158
159
        return strpos($mode, 'w') !== false || strpos($mode, '+') !== false;
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    public function write($string): int
166
    {
167
        $bytesWritten = false;
168
169
        if ($this->stream && $this->isWritable()) {
170
            $bytesWritten = fwrite($this->stream, $string);
171
        }
172
173
        if ($bytesWritten !== false) {
174
            return $bytesWritten;
175
        }
176
177
        throw new RuntimeException('Unable to write to stream/resource');
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183
    public function isReadable(): bool
184
    {
185
        if (! $this->stream) {
186
            return false;
187
        }
188
189
        /** @var mixed $mode */
190
        $mode = $this->getMetadata('mode');
191
192
        if (! is_string($mode)) {
193
            return false;
194
        }
195
196
        return strpos($mode, 'r') !== false || strpos($mode, '+') !== false;
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202
    public function read($length): string
203
    {
204
        $dataRead = false;
205
206
        if ($this->stream && $this->isReadable()) {
207
            $dataRead = fread($this->stream, $length);
208
        }
209
210
        if (is_string($dataRead)) {
211
            return $dataRead;
212
        }
213
214
        throw new RuntimeException('Unable to read from stream/resource');
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220
    public function getContents()
221
    {
222
        if (! $this->stream) {
223
            return '';
224
        }
225
226
        $contents = stream_get_contents($this->stream);
227
228
        return $contents === false ? '' : $contents;
229
    }
230
231
    /**
232
     * {@inheritdoc}
233
     */
234
    public function getMetadata($key = null)
235
    {
236
        if (! $this->stream) {
237
            return null;
238
        }
239
240
        $metadata = stream_get_meta_data($this->stream);
241
242
        if ($key === null) {
243
            return $metadata;
244
        }
245
246
        return $metadata[$key] ?? null;
247
    }
248
}
249