Completed
Pull Request — master (#9)
by Anton
07:26
created

PSR7Client::getWorker()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * High-performance PHP process supervisor and load balancer written in Go
4
 *
5
 * @author Wolfy-J
6
 */
7
8
namespace Spiral\RoadRunner;
9
10
use Psr\Http\Message\ResponseInterface;
11
use Psr\Http\Message\ServerRequestInterface;
12
use Zend\Diactoros;
13
14
/**
15
 * Manages PSR-7 request and response.
16
 */
17
class PSR7Client
18
{
19
    /**
20
     * @varWorker
21
     */
22
    private $worker;
23
24
    /**
25
     * @param Worker $worker
26
     */
27
    public function __construct(Worker $worker)
28
    {
29
        $this->worker = $worker;
30
    }
31
32
    /**
33
     * @return Worker
34
     */
35
    public function getWorker(): Worker
36
    {
37
        return $this->worker;
38
    }
39
40
    /**
41
     * @return ServerRequestInterface|null
42
     */
43
    public function acceptRequest()
44
    {
45
        $body = $this->worker->receive($ctx);
46
        if (empty($body) && empty($ctx)) {
47
            // termination request
48
            return null;
49
        }
50
51
        if (empty($ctx = json_decode($ctx, true))) {
52
            // invalid context
53
            return null;
54
        }
55
56
        parse_str($ctx['rawQuery'], $query);
57
58
        $bodyStream = 'php://input';
59
        $parsedBody = null;
60
        if ($ctx['parsed']) {
61
            $parsedBody = json_decode($body, true);
62
        } elseif ($body != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $body of type Error|null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
63
            $bodyStream = new Diactoros\Stream("php://memory", "rwb");
64
            $bodyStream->write($body);
0 ignored issues
show
Bug introduced by
It seems like $body defined by $this->worker->receive($ctx) on line 45 can also be of type object<Error>; however, Zend\Diactoros\Stream::write() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
65
        }
66
67
        return new Diactoros\ServerRequest(
68
            $_SERVER,
69
            $this->wrapUploads($ctx['uploads']),
70
            $ctx['uri'],
71
            $ctx['method'],
72
            $bodyStream,
73
            $ctx['headers'],
74
            $ctx['cookies'],
75
            $query,
0 ignored issues
show
Bug introduced by
It seems like $query can also be of type null; however, Zend\Diactoros\ServerRequest::__construct() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
76
            $parsedBody,
77
            $ctx['protocol']
78
        );
79
    }
80
81
    /**
82
     * Send response to the application server.
83
     *
84
     * @param ResponseInterface $response
85
     */
86
    public function respond(ResponseInterface $response)
87
    {
88
        $headers = $response->getHeaders();
89
        if (empty($headers)) {
90
            // this is required to represent empty header set as map and not as array
91
            $headers = new \stdClass();
92
        }
93
94
        $this->worker->send($response->getBody(), json_encode([
95
            'status'  => $response->getStatusCode(),
96
            'headers' => $headers
97
        ]));
98
    }
99
100
    /**
101
     * Wraps all uploaded files with UploadedFile.
102
     *
103
     * @param array $files
104
     *
105
     * @return array
106
     */
107
    private function wrapUploads($files): array
108
    {
109
        if (empty($files)) {
110
            return [];
111
        }
112
113
        $result = [];
114
        foreach ($files as $index => $file) {
115
            if (!isset($file['name'])) {
116
                $result[$index] = $this->wrapUploads($file);
117
                continue;
118
            }
119
120
            $result[$index] = new Diactoros\UploadedFile(
121
                $file['tmpName'],
122
                $file['size'],
123
                $file['error'],
124
                $file['name'],
125
                $file['mime']
126
            );
127
        }
128
129
        return $result;
130
    }
131
}