HasHttpRequests::setHandlerStack()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the docodeit/wechat.
5
 *
6
 * (c) docodeit <[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 JinWeChat\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 docodeit <[email protected]>
23
 */
24
trait HasHttpRequests
25
{
26
    /**
27
     * @var \GuzzleHttp\ClientInterface
28
     */
29
    protected $httpClient;
30
31
    /**
32
     * @var array
33
     */
34
    protected $middlewares = [];
35
36
    /**
37
     * @var \GuzzleHttp\HandlerStack
38
     */
39
    protected $handlerStack;
40
41
    /**
42
     * @var array
43
     */
44
    protected static $defaults = [
45
        'curl' => [
46
            CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
47
        ],
48
    ];
49
50
    /**
51
     * Set guzzle default settings.
52
     *
53
     * @param array $defaults
54
     */
55
    public static function setDefaultOptions($defaults = [])
56
    {
57
        self::$defaults = $defaults;
58
    }
59
60
    /**
61
     * Return current guzzle default settings.
62
     *
63
     * @return array
64
     */
65
    public static function getDefaultOptions(): array
66
    {
67
        return self::$defaults;
68
    }
69
70
    /**
71
     * Set GuzzleHttp\Client.
72
     *
73
     * @param \GuzzleHttp\ClientInterface $httpClient
74
     *
75
     * @return $this
76
     */
77
    public function setHttpClient(ClientInterface $httpClient)
78
    {
79
        $this->httpClient = $httpClient;
80
81
        return $this;
82
    }
83
84
    /**
85
     * Return GuzzleHttp\Client instance.
86
     *
87
     * @return \GuzzleHttp\Client
88
     */
89
    public function getHttpClient(): Client
90
    {
91
        if (!($this->httpClient instanceof ClientInterface)) {
0 ignored issues
show
introduced by
$this->httpClient is always a sub-type of GuzzleHttp\ClientInterface.
Loading history...
92
            $this->httpClient = new Client();
93
        }
94
95
        return $this->httpClient;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->httpClient returns the type GuzzleHttp\ClientInterface which includes types incompatible with the type-hinted return GuzzleHttp\Client.
Loading history...
96
    }
97
98
    /**
99
     * Add a middleware.
100
     *
101
     * @param callable    $middleware
102
     * @param null|string $name
103
     *
104
     * @return $this
105
     */
106
    public function pushMiddleware(callable $middleware, string $name = null)
107
    {
108
        if (!is_null($name)) {
109
            $this->middlewares[$name] = $middleware;
110
        } else {
111
            array_push($this->middlewares, $middleware);
112
        }
113
114
        return $this;
115
    }
116
117
    /**
118
     * Return all middlewares.
119
     *
120
     * @return array
121
     */
122
    public function getMiddlewares(): array
123
    {
124
        return $this->middlewares;
125
    }
126
127
    /**
128
     * Make a request.
129
     *
130
     * @param string $url
131
     * @param string $method
132
     * @param array  $options
133
     *
134
     * @return \Psr\Http\Message\ResponseInterface
135
     */
136
    public function request($url, $method = 'GET', $options = []): ResponseInterface
137
    {
138
        $method = strtoupper($method);
139
140
        $options = array_merge(self::$defaults, $options, ['handler' => $this->getHandlerStack()]);
141
142
        $options = $this->fixJsonIssue($options);
143
144
        if (property_exists($this, 'baseUri') && !is_null($this->baseUri)) {
145
            $options['base_uri'] = $this->baseUri;
146
        }
147
148
        $response = $this->getHttpClient()->request($method, $url, $options);
149
        $response->getBody()->rewind();
150
151
        return $response;
152
    }
153
154
    /**
155
     * @param \GuzzleHttp\HandlerStack $handlerStack
156
     *
157
     * @return $this
158
     */
159
    public function setHandlerStack(HandlerStack $handlerStack)
160
    {
161
        $this->handlerStack = $handlerStack;
162
163
        return $this;
164
    }
165
166
    /**
167
     * Build a handler stack.
168
     *
169
     * @return \GuzzleHttp\HandlerStack
170
     */
171
    public function getHandlerStack(): HandlerStack
172
    {
173
        if ($this->handlerStack) {
174
            return $this->handlerStack;
175
        }
176
177
        $this->handlerStack = HandlerStack::create();
178
179
        foreach ($this->middlewares as $name => $middleware) {
180
            $this->handlerStack->push($middleware, $name);
181
        }
182
183
        return $this->handlerStack;
184
    }
185
186
    /**
187
     * @param array $options
188
     *
189
     * @return array
190
     */
191
    protected function fixJsonIssue(array $options): array
192
    {
193
        if (isset($options['json']) && is_array($options['json'])) {
194
            $options['headers'] = array_merge($options['headers'] ?? [], ['Content-Type' => 'application/json']);
195
196
            if (empty($options['json'])) {
197
                $options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_FORCE_OBJECT);
198
            } else {
199
                $options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_UNESCAPED_UNICODE);
200
            }
201
202
            unset($options['json']);
203
        }
204
205
        return $options;
206
    }
207
}
208