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

StreamHandler::withEncoder()   A

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 1
Metric Value
cc 1
eloc 3
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
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|Socket|string|null
31
     */
32
    private $uri = null;
33
34
    /**
35
     * @param mixed|resource|string $uri
36
     */
37 17
    public function __construct(
38
        mixed $uri = 'udp://127.0.0.1:8890'
39
    ) {
40 17
        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 16
        $this->uri = $uri;
49
    }
50
51
    /**
52
     * Encodes {@param $variable} with {@see self::$encoder} and sends the result to the stream.
0 ignored issues
show
Bug introduced by
The type Yiisoft\VarDumper\Handler\with 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 15
    public function handle(mixed $variable, int $depth, bool $highlight = false): void
55
    {
56 15
        $data = ($this->encoder ?? '\json_encode')($variable);
57 15
        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 14
        if (!is_resource($this->stream) && !$this->stream instanceof Socket) {
67 14
            $this->initializeStream();
68
        }
69
70 14
        if ($this->stream instanceof Socket) {
71 1
            socket_write($this->stream, $data, strlen($data));
72 1
            return;
73
        }
74
75
        /** @psalm-suppress PossiblyNullArgument */
76 13
        if (@fwrite($this->stream, $data) === false) {
77 1
            $this->initializeStream();
78
79 1
            if ($this->stream instanceof Socket) {
80
                socket_write($this->stream, $data, strlen($data));
81
                return;
82
            }
83
84
            /** @psalm-suppress PossiblyNullArgument */
85 1
            if (@fwrite($this->stream, $data) === false) {
86
                throw new RuntimeException('Cannot write a stream.');
87
            }
88
        }
89
    }
90
91 3
    public function withEncoder(callable $encoder): HandlerInterface
92
    {
93 3
        $new = clone $this;
94 3
        $new->encoder = $encoder;
95 3
        return $new;
96
    }
97
98 14
    private function initializeStream(): void
99
    {
100 14
        if (is_string($this->uri)) {
101
            if (
102 3
                str_starts_with($this->uri, 'udp://') ||
103 3
                str_starts_with($this->uri, 'udg://') ||
104 1
                str_starts_with($this->uri, 'tcp://') ||
105 3
                str_starts_with($this->uri, 'unix://')
106
            ) {
107 2
                $this->stream = fsockopen($this->uri);
108
            } else {
109 3
                $this->stream = fopen($this->uri, 'wb+');
110
            }
111
        } else {
112 11
            $this->stream = $this->uri;
113
        }
114
115 14
        if (!is_resource($this->stream) && !$this->stream instanceof Socket) {
116 1
            throw new RuntimeException('Cannot initialize a stream.');
117
        }
118
    }
119
120 16
    public function __destruct()
121
    {
122 16
        if (!is_string($this->uri) || !is_resource($this->stream)) {
123 14
            return;
124
        }
125 3
        fclose($this->stream);
126
    }
127
}
128