Passed
Pull Request — master (#95)
by Dmitriy
02:32
created

StreamHandler   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Test Coverage

Coverage 92.68%

Importance

Changes 4
Bugs 1 Features 1
Metric Value
wmc 16
eloc 35
c 4
b 1
f 1
dl 0
loc 92
ccs 38
cts 41
cp 0.9268
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __destruct() 0 7 3
A withEncoder() 0 5 1
A writeToStream() 0 6 2
A initializeStream() 0 10 3
A __construct() 0 12 4
A handle() 0 18 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\VarDumper\Handler;
6
7
use InvalidArgumentException;
8
use RuntimeException;
9
use Socket;
10
use Yiisoft\VarDumper\HandlerInterface;
11
12
use function fsockopen;
13
use function fwrite;
14
use function get_debug_type;
15
use function is_resource;
16
use function is_string;
17
18
final class StreamHandler implements HandlerInterface
19
{
20
    /**
21
     * @var callable|null
22
     */
23
    private $encoder = null;
24
    /**
25
     * @var resource|Socket|null
26
     */
27
    private $stream = null;
28
29
    /**
30
     * @var resource|string|Socket|null
31
     */
32
    private $uri = null;
33
34
    /**
35
     * @param mixed|resource|string $uri
36
     */
37 13
    public function __construct(
38
        mixed $uri = 'udp://127.0.0.1:8890'
39
    ) {
40 13
        if (!is_string($uri) && !is_resource($uri) && !$uri instanceof Socket) {
41 1
            throw new InvalidArgumentException(
42 1
                sprintf(
43 1
                    'Argument $uri must be a string or a resource, "%s" given.',
44 1
                    get_debug_type($uri)
45 1
                )
46 1
            );
47
        }
48 12
        $this->uri = $uri;
49
    }
50
51
    /**
52
     * Encodes with {@see self::$encoder} {@param $variable} and sends the result to the stream.
0 ignored issues
show
Bug introduced by
The type Yiisoft\VarDumper\Handler\and was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
53
     */
54 12
    public function handle(mixed $variable, int $depth, bool $highlight = false): void
55
    {
56 12
        $data = ($this->encoder ?? '\json_encode')($variable);
57 12
        if (!is_string($data)) {
58 1
            throw new RuntimeException(
59 1
                sprintf(
60 1
                    'Encoder must return a string, %s returned.',
61 1
                    get_debug_type($data)
62 1
                )
63 1
            );
64
        }
65
66 11
        $this->initializeStream();
67
68 11
        if (!$this->writeToStream($data)) {
69
            $this->initializeStream();
70
71
            $this->writeToStream($data);
72
        }
73
    }
74
75 2
    public function withEncoder(callable $encoder): HandlerInterface
76
    {
77 2
        $new = clone $this;
78 2
        $new->encoder = $encoder;
79 2
        return $new;
80
    }
81
82 11
    private function initializeStream(): void
83
    {
84 11
        if (is_string($this->uri)) {
85 2
            $this->stream = fsockopen($this->uri);
86
        } else {
87 9
            $this->stream = $this->uri;
88
        }
89
90 11
        if (!is_resource($this->stream)) {
91 1
            throw new RuntimeException('Cannot initialize a stream.');
92
        }
93
    }
94
95 11
    private function writeToStream(string $data): bool
96
    {
97 11
        if (!is_resource($this->stream)) {
98
            return false;
99
        }
100 11
        return @fwrite($this->stream, $data) !== false;
101
    }
102
103 12
    public function __destruct()
104
    {
105 12
        if (is_resource($this->stream)) {
106 10
            fclose($this->stream);
107
        }
108 12
        if (is_string($this->uri)) {
109 2
            @unlink($this->uri);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

109
            /** @scrutinizer ignore-unhandled */ @unlink($this->uri);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
110
        }
111
    }
112
}
113