Issues (32)

src/Client/Methods.php (5 issues)

1
<?php
2
/**
3
 * Client static commands
4
 * User: moyo
5
 * Date: 06/12/2017
6
 * Time: 2:05 PM
7
 */
8
9
namespace Carno\HTTP\Client;
10
11
use Carno\HTTP\Exception\InvalidRequestException;
12
use Carno\HTTP\Exception\NonrecognitionPayloadException;
13
use Carno\HTTP\Exception\RequestException;
14
use Carno\HTTP\Exception\ResponseException;
15
use Carno\HTTP\Options;
16
use Carno\HTTP\Standard\Request;
17
use Carno\HTTP\Standard\Response;
18
use Carno\HTTP\Standard\Streams\Body;
19
use Carno\HTTP\Standard\Streams\Form;
20
use Carno\HTTP\Standard\Uri;
21
use Psr\Http\Message\StreamInterface;
22
23
trait Methods
24
{
25
    /**
26
     * @param string $url
27
     * @param array $headers
28
     * @param Options $options
29
     * @return Responding
30
     * @throws RequestException
31
     * @throws ResponseException
32
     */
33
    public static function get(string $url, array $headers = [], Options $options = null)
34
    {
35
        return self::request('GET', $url, $headers, null, $options);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::request('GE...eaders, null, $options) also could return the type Carno\HTTP\Client\Framing which is incompatible with the documented return type Carno\HTTP\Client\Responding.
Loading history...
36
    }
37
38
    /**
39
     * @param string $url
40
     * @param mixed $payload
41
     * @param array $headers
42
     * @param Options $options
43
     * @return Responding
44
     * @throws RequestException
45
     * @throws ResponseException
46
     */
47
    public static function post(string $url, $payload = null, array $headers = [], Options $options = null)
48
    {
49
        return self::request('POST', $url, $headers, self::p2stream($payload, $headers), $options);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::request('PO...d, $headers), $options) also could return the type Carno\HTTP\Client\Framing which is incompatible with the documented return type Carno\HTTP\Client\Responding.
Loading history...
50
    }
51
52
    /**
53
     * @param string $url
54
     * @param array $headers
55
     * @param Options $options
56
     * @return Responding
57
     * @throws RequestException
58
     * @throws ResponseException
59
     */
60
    public static function delete(string $url, array $headers = [], Options $options = null)
61
    {
62
        return self::request('DELETE', $url, $headers, null, $options);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::request('DE...eaders, null, $options) also could return the type Carno\HTTP\Client\Framing which is incompatible with the documented return type Carno\HTTP\Client\Responding.
Loading history...
63
    }
64
65
    /**
66
     * @param string $url
67
     * @param array $headers
68
     * @param Options $options
69
     * @return Framing
70
     * @throws RequestException
71
     * @throws ResponseException
72
     */
73
    public static function upgrade(string $url, array $headers = [], Options $options = null)
74
    {
75
        return self::request('UPGRADE', $url, self::f2headers($headers, ['connection']), null, $options);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::request('UP...ion')), null, $options) also could return the type Carno\HTTP\Client\Responding which is incompatible with the documented return type Carno\HTTP\Client\Framing.
Loading history...
76
    }
77
78
    /**
79
     * @param string $method
80
     * @param string $url
81
     * @param array $headers
82
     * @param StreamInterface $stream
83
     * @param Options $options
84
     * @return Responding|Framing
85
     * @throws RequestException
86
     * @throws ResponseException
87
     */
88
    private static function request(
89
        string $method,
90
        string $url,
91
        array $headers = [],
92
        StreamInterface $stream = null,
93
        Options $options = null
94
    ) {
95
        $p = parse_url($url);
96
97
        $req = new Request(
98
            $method,
99
            $uri = new Uri(
100
                $p['scheme'] ?? 'http',
101
                $host = $p['host'] ?? 'localhost',
102
                $port = $p['port'] ?? null,
103
                $p['path'] ?? '/',
104
                $p['query'] ?? null,
105
                $p['fragment'] ?? null
106
            ),
107
            $headers,
108
            $stream
109
        );
110
111
        if (is_null($port) && is_null($port = $uri->getPort())) {
112
            throw new InvalidRequestException('Unknown port from url');
113
        }
114
115
        $got = yield Persistent::assign($host, $port, $headers, $options)->perform($req);
0 ignored issues
show
Bug Best Practice introduced by
The expression yield Carno\HTTP\Client\...options)->perform($req) returns the type Generator which is incompatible with the documented return type Carno\HTTP\Client\Framin...\HTTP\Client\Responding.
Loading history...
116
117
        return $got instanceof Response ? new Responding($got) : $got;
118
    }
119
120
    /**
121
     * @param mixed $input
122
     * @param array $headers
123
     * @return StreamInterface
124
     */
125
    private static function p2stream($input, array $headers) : StreamInterface
126
    {
127
        switch (gettype($input)) {
128
            case 'string':
129
                return new Body($input);
130
            case 'array':
131
                if ((array_change_key_case($headers, CASE_LOWER)['content-type'] ?? null) === 'application/json') {
132
                    return new Body(json_encode($input, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
133
                }
134
                return new Form($input);
135
            case 'object':
136
                if ($input instanceof StreamInterface) {
137
                    return $input;
138
                }
139
                break;
140
            case 'NULL':
141
                return new Body('');
142
        }
143
144
        throw new NonrecognitionPayloadException;
145
    }
146
147
    /**
148
     * @param array $headers
149
     * @param array $removes
150
     * @return array
151
     */
152
    private static function f2headers(array $headers, array $removes) : array
153
    {
154
        foreach ($headers as $name => $val) {
155
            if (in_array(strtolower($name), array_change_key_case($removes, CASE_LOWER))) {
156
                unset($headers[$name]);
157
            }
158
        }
159
        return $headers;
160
    }
161
}
162