Completed
Push — master ( 28f1e1...eed622 )
by Carlos
07:52
created

HasHttpRequests::resolveResponse()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 16
nc 6
nop 2
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
ccs 0
cts 16
cp 0
crap 42
1
<?php
2
3
/*
4
 * This file is part of the overtrue/wechat.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace EasyWeChat\Kernel\Traits;
13
14
use GuzzleHttp\Client;
15
use GuzzleHttp\ClientInterface;
16
use GuzzleHttp\HandlerStack;
17
use Psr\Http\Message\ResponseInterface;
18
19
/**
20
 * Trait HasHttpRequests.
21
 *
22
 * @author overtrue <[email protected]>
23
 */
24
trait HasHttpRequests
25
{
26
    use ResponseCastable;
27
28
    /**
29
     * @var \GuzzleHttp\ClientInterface
30
     */
31
    protected $httpClient;
32
33
    /**
34
     * @var array
35
     */
36
    protected $middlewares = [];
37
38
    /**
39
     * @var \GuzzleHttp\HandlerStack
40
     */
41
    protected $handlerStack;
42
43
    /**
44
     * @var array
45
     */
46
    protected static $defaults = [
47
        'curl' => [
48
            CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
49
        ],
50
    ];
51
52
    /**
53
     * Set guzzle default settings.
54
     *
55
     * @param array $defaults
56
     */
57
    public static function setDefaultOptions($defaults = [])
58
    {
59
        self::$defaults = $defaults;
60
    }
61
62
    /**
63
     * Return current guzzle default settings.
64
     *
65
     * @return array
66
     */
67
    public static function getDefaultOptions(): array
68
    {
69
        return self::$defaults;
70
    }
71
72
    /**
73
     * Set GuzzleHttp\Client.
74
     *
75
     * @param \GuzzleHttp\ClientInterface $httpClient
76
     *
77
     * @return $this
78
     */
79
    public function setHttpClient(ClientInterface $httpClient)
80
    {
81
        $this->httpClient = $httpClient;
82
83
        return $this;
84
    }
85
86
    /**
87
     * Return GuzzleHttp\Client instance.
88
     *
89
     * @return \GuzzleHttp\Client
90
     */
91
    public function getHttpClient(): Client
92
    {
93
        if (!($this->httpClient instanceof ClientInterface)) {
94
            $this->httpClient = new Client();
95
        }
96
97
        return $this->httpClient;
98
    }
99
100
    /**
101
     * Add a middleware.
102
     *
103
     * @param callable    $middleware
104
     * @param null|string $name
105
     *
106
     * @return $this
107
     */
108
    public function pushMiddleware(callable $middleware, string $name = null)
109
    {
110
        if (!is_null($name)) {
111
            $this->middlewares[$name] = $middleware;
112
        } else {
113
            array_push($this->middlewares, $middleware);
114
        }
115
116
        return $this;
117
    }
118
119
    /**
120
     * Return all middlewares.
121
     *
122
     * @return array
123
     */
124
    public function getMiddlewares(): array
125
    {
126
        return $this->middlewares;
127
    }
128
129
    /**
130
     * Make a request.
131
     *
132
     * @param string $url
133
     * @param string $method
134
     * @param array  $options
135
     *
136
     * @return \Psr\Http\Message\ResponseInterface|\EasyWeChat\Kernel\Support\Collection|array|object|string
137
     */
138
    public function request($url, $method = 'GET', $options = []): ResponseInterface
139
    {
140
        $method = strtoupper($method);
141
142
        $options = array_merge(self::$defaults, $options, ['handler' => $this->getHandlerStack()]);
143
144
        $options = $this->fixJsonIssue($options);
145
146
        if (property_exists($this, 'baseUri') && !is_null($this->baseUri)) {
147
            $options['base_uri'] = $this->baseUri;
0 ignored issues
show
Bug introduced by
The property baseUri does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
148
        }
149
150
        $response = $this->getHttpClient()->request($method, $url, $options);
151
        $response->getBody()->rewind();
152
153
        return $response;
154
    }
155
156
    /**
157
     * @param \GuzzleHttp\HandlerStack $handlerStack
158
     *
159
     * @return $this
160
     */
161
    public function setHandlerStack(HandlerStack $handlerStack)
162
    {
163
        $this->handlerStack = $handlerStack;
164
165
        return $this;
166
    }
167
168
    /**
169
     * Build a handler stack.
170
     *
171
     * @return \GuzzleHttp\HandlerStack
172
     */
173
    public function getHandlerStack(): HandlerStack
174
    {
175
        if ($this->handlerStack) {
176
            return $this->handlerStack;
177
        }
178
179
        $this->handlerStack = HandlerStack::create();
180
181
        foreach ($this->middlewares as $name => $middleware) {
182
            $this->handlerStack->push($middleware, $name);
183
        }
184
185
        return $this->handlerStack;
186
    }
187
188
    /**
189
     * @param array $options
190
     *
191
     * @return array
192
     */
193
    protected function fixJsonIssue(array $options): array
194
    {
195
        if (isset($options['json']) && is_array($options['json'])) {
196
            $options['headers'] = array_merge($options['headers'] ?? [], ['Content-Type' => 'application/json']);
197
198
            if (empty($options['json'])) {
199
                $options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_FORCE_OBJECT);
200
            } else {
201
                $options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_UNESCAPED_UNICODE);
202
            }
203
204
            unset($options['json']);
205
        }
206
207
        return $options;
208
    }
209
}
210