Issues (83)

src/Kernel/Traits/HasHttpRequests.php (5 issues)

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 1
    public static function setDefaultOptions($defaults = [])
58
    {
59 1
        self::$defaults = $defaults;
60 1
    }
61
62
    /**
63
     * Return current guzzle default settings.
64
     *
65
     * @return array
66
     */
67 1
    public static function getDefaultOptions(): array
68
    {
69 1
        return self::$defaults;
70
    }
71
72
    /**
73
     * Set GuzzleHttp\Client.
74
     *
75
     * @param \GuzzleHttp\ClientInterface $httpClient
76
     *
77
     * @return $this
78
     */
79 73
    public function setHttpClient(ClientInterface $httpClient)
80
    {
81 73
        $this->httpClient = $httpClient;
82
83 73
        return $this;
84
    }
85
86
    /**
87
     * Return GuzzleHttp\ClientInterface instance.
88
     *
89
     * @return ClientInterface
90
     */
91 4
    public function getHttpClient(): ClientInterface
92
    {
93 4
        if (!($this->httpClient instanceof ClientInterface)) {
0 ignored issues
show
$this->httpClient is always a sub-type of GuzzleHttp\ClientInterface.
Loading history...
94 2
            if (property_exists($this, 'app') && $this->app['http_client']) {
95 1
                $this->httpClient = $this->app['http_client'];
96
            } else {
97 1
                $this->httpClient = new Client(['handler' => HandlerStack::create($this->getGuzzleHandler())]);
98
            }
99
        }
100
101 4
        return $this->httpClient;
102
    }
103
104
    /**
105
     * Add a middleware.
106
     *
107
     * @param callable $middleware
108
     * @param string   $name
109
     *
110
     * @return $this
111
     */
112 10
    public function pushMiddleware(callable $middleware, string $name = null)
113
    {
114 10
        if (!is_null($name)) {
115 10
            $this->middlewares[$name] = $middleware;
116
        } else {
117 1
            array_push($this->middlewares, $middleware);
118
        }
119
120 10
        return $this;
121
    }
122
123
    /**
124
     * Return all middlewares.
125
     *
126
     * @return array
127
     */
128 1
    public function getMiddlewares(): array
129
    {
130 1
        return $this->middlewares;
131
    }
132
133
    /**
134
     * Make a request.
135
     *
136
     * @param string $url
137
     * @param string $method
138
     * @param array  $options
139
     *
140
     * @return \Psr\Http\Message\ResponseInterface
141
     *
142
     * @throws \GuzzleHttp\Exception\GuzzleException
143
     */
144 2
    public function request($url, $method = 'GET', $options = []): ResponseInterface
145
    {
146 2
        $method = strtoupper($method);
147
148 2
        $options = array_merge(self::$defaults, $options, ['handler' => $this->getHandlerStack()]);
149
150 2
        $options = $this->fixJsonIssue($options);
151
152 2
        if (property_exists($this, 'baseUri') && !is_null($this->baseUri)) {
153 2
            $options['base_uri'] = $this->baseUri;
154
        }
155
156 2
        $response = $this->getHttpClient()->request($method, $url, $options);
157 2
        $response->getBody()->rewind();
158
159 2
        return $response;
160
    }
161
162
    /**
163
     * @param \GuzzleHttp\HandlerStack $handlerStack
164
     *
165
     * @return $this
166
     */
167 1
    public function setHandlerStack(HandlerStack $handlerStack)
168
    {
169 1
        $this->handlerStack = $handlerStack;
170
171 1
        return $this;
172
    }
173
174
    /**
175
     * Build a handler stack.
176
     *
177
     * @return \GuzzleHttp\HandlerStack
178
     */
179 1
    public function getHandlerStack(): HandlerStack
180
    {
181 1
        if ($this->handlerStack) {
182 1
            return $this->handlerStack;
183
        }
184
185 1
        $this->handlerStack = HandlerStack::create($this->getGuzzleHandler());
186
187 1
        foreach ($this->middlewares as $name => $middleware) {
188 1
            $this->handlerStack->push($middleware, $name);
189
        }
190
191 1
        return $this->handlerStack;
192
    }
193
194
    /**
195
     * @param array $options
196
     *
197
     * @return array
198
     */
199 2
    protected function fixJsonIssue(array $options): array
200
    {
201 2
        if (isset($options['json']) && is_array($options['json'])) {
202 1
            $options['headers'] = array_merge($options['headers'] ?? [], ['Content-Type' => 'application/json']);
203
204 1
            if (empty($options['json'])) {
205 1
                $options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_FORCE_OBJECT);
0 ignored issues
show
Deprecated Code introduced by
The function GuzzleHttp\json_encode() has been deprecated: json_encode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonEncode instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

205
                $options['body'] = /** @scrutinizer ignore-deprecated */ \GuzzleHttp\json_encode($options['json'], JSON_FORCE_OBJECT);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
206
            } else {
207 1
                $options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_UNESCAPED_UNICODE);
0 ignored issues
show
Deprecated Code introduced by
The function GuzzleHttp\json_encode() has been deprecated: json_encode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonEncode instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

207
                $options['body'] = /** @scrutinizer ignore-deprecated */ \GuzzleHttp\json_encode($options['json'], JSON_UNESCAPED_UNICODE);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
208
            }
209
210 1
            unset($options['json']);
211
        }
212
213 2
        return $options;
214
    }
215
216
    /**
217
     * Get guzzle handler.
218
     *
219
     * @return callable
220
     */
221 2
    protected function getGuzzleHandler()
222
    {
223 2
        if (property_exists($this, 'app') && isset($this->app['guzzle_handler'])) {
224
            return is_string($handler = $this->app->raw('guzzle_handler'))
0 ignored issues
show
Bug Best Practice introduced by
The expression return is_string($handle...w $handler() : $handler also could return the type object which is incompatible with the documented return type callable.
Loading history...
225
                        ? new $handler()
226
                        : $handler;
227
        }
228
229 2
        return \GuzzleHttp\choose_handler();
0 ignored issues
show
Deprecated Code introduced by
The function GuzzleHttp\choose_handler() has been deprecated: choose_handler will be removed in guzzlehttp/guzzle:8.0. Use Utils::chooseHandler instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

229
        return /** @scrutinizer ignore-deprecated */ \GuzzleHttp\choose_handler();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
230
    }
231
}
232