Completed
Push — master ( 06dbdb...3b3e36 )
by do
05:48
created

BaseClient::retryMiddleware()   B

Complexity

Conditions 6
Paths 1

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 13
nc 1
nop 0
dl 0
loc 23
ccs 0
cts 17
cp 0
crap 42
rs 8.5906
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;
13
14
use GuzzleHttp\Client;
15
use GuzzleHttp\MessageFormatter;
16
use GuzzleHttp\Middleware;
17
use JinWeChat\Kernel\Contracts\CookiesInterface;
18
use JinWeChat\Kernel\Http\Response;
19
use JinWeChat\Kernel\Traits\HasHttpRequests;
20
use Monolog\Logger;
21
use Psr\Http\Message\RequestInterface;
22
use Psr\Http\Message\ResponseInterface;
23
24
/**
25
 * Class BaseClient.
26
 *
27
 * @author docodeit <[email protected]>
28
 */
29
class BaseClient
30
{
31
    use HasHttpRequests {
32
        request as performRequest;
33
    }
34
35
    /**
36
     * @var \JinWeChat\Kernel\ServiceContainer
37
     */
38
    protected $app;
39
40
    /**
41
     * @var \JinWeChat\Kernel\Contracts\CookiesInterface
42
     */
43
    protected $cookies;
44
    /**
45
     * @var string
46
     */
47
    protected $referrer;
48
49
    /**
50
     * @var int
51
     */
52
    protected $token;
53
54
    /**
55
     * @var
56
     */
57
    protected $baseUri;
58
59
    /**
60
     * BaseClient constructor.
61
     *
62
     * @param \JinWeChat\Kernel\ServiceContainer $app
63
     * @param \JinWeChat\Kernel\Contracts\CookiesInterface|null $cookies
64
     */
65
    public function __construct(ServiceContainer $app, CookiesInterface $cookies = null)
0 ignored issues
show
Unused Code introduced by
The parameter $cookies is not used and could be removed. ( Ignorable by Annotation )

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

65
    public function __construct(ServiceContainer $app, /** @scrutinizer ignore-unused */ CookiesInterface $cookies = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
66
    {
67
        $this->app = $app;
68
        $this->referrer = $app['config']->get('http.base_uri', 'https://mp.weixin.qq.com/');
69
    }
70
71
    /**
72
     * GET request.
73
     *
74
     * @param string $url
75
     * @param array $query
76
     *
77
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
78
     *
79
     * @return \Psr\Http\Message\ResponseInterface
80
     */
81
    public function httpGet(string $url, array $query = [])
82
    {
83
        return $this->request($url, 'GET', $query);
84
    }
85
86
    /**
87
     * POST request
88
     * @param string $url
89
     * @param array $data
90
     *
91
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
92
     *
93
     * @return \Psr\Http\Message\ResponseInterface
94
     */
95
    public function httpPost(string $url, array $data = [])
96
    {
97
        return $this->request($url, 'POST', ['form_params' => $data]);
98
    }
99
100
    /**
101
     * JSON request.
102
     *
103
     * @param string $url
104
     * @param string|array $data
105
     * @param array $query
106
     *
107
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
108
     *
109
     * @return \Psr\Http\Message\ResponseInterface
110
     */
111
    public function httpPostJson(string $url, array $data = [], array $query = [])
112
    {
113
        return $this->request($url, 'POST', ['query' => $query, 'json' => $data]);
114
    }
115
116
    /**
117
     * Upload file.
118
     *
119
     * @param string $url
120
     * @param array $files
121
     * @param array $form
122
     * @param array $query
123
     *
124
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
125
     *
126
     * @return \Psr\Http\Message\ResponseInterface
127
     */
128
    public function httpUpload(string $url, array $files = [], array $form = [], array $query = [])
129
    {
130
        $multipart = [];
131
132
        foreach ($files as $name => $path) {
133
            $multipart[] = [
134
                'name' => $name,
135
                'contents' => fopen($path, 'r'),
136
            ];
137
        }
138
139
        foreach ($form as $name => $contents) {
140
            $multipart[] = compact('name', 'contents');
141
        }
142
143
        return $this->request($url, 'POST', ['query' => $query, 'multipart' => $multipart]);
144
    }
145
146
    /**
147
     * @param string $url
148
     * @param string $method
149
     * @param array $options
150
     * @param bool $returnRaw
151
     *
152
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
153
     *
154
     * @return \Psr\Http\Message\ResponseInterface
155
     */
156
    public function request(string $url, string $method = 'GET', array $options = [], $returnRaw = false)
157
    {
158
        if (empty($this->middlewares)) {
159
            $this->registerHttpMiddlewares();
160
        }
161
162
        $response = $this->performRequest($url, $method, $options);
163
        //保存Token todo::改为缓存
164
        if (preg_match('/cgi-bin\/bizlogin?action=startlogin/',$url,$urlMatch)){
165
            if (preg_match('/token=([\d]+)/i', $response['redirect_url'], $match)) {
166
                $this->token = $match[1];
167
            }
168
        }
169
170
        return $returnRaw ? $response : $this->castResponseToType($response, $this->app->config->get('response_type'));
171
    }
172
173
    /**
174
     * @param string $url
175
     * @param string $method
176
     * @param array $options
177
     *
178
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
179
     *
180
     * @return \JinWeChat\Kernel\Http\Response
181
     */
182
    public function requestRaw(string $url, string $method = 'GET', array $options = [])
183
    {
184
        return Response::buildFromPsrResponse($this->request($url, $method, $options, true));
185
    }
186
187
    /**
188
     * Return GuzzleHttp\Client instance.
189
     *
190
     * @return \GuzzleHttp\Client
191
     */
192
    public function getHttpClient(): Client
193
    {
194
        if (!($this->httpClient instanceof Client)) {
195
            $this->httpClient = $this->app['http_client'] ?? new Client();
196
        }
197
198
        return $this->httpClient;
199
    }
200
201
    /**
202
     * Register Guzzle middlewares.
203
     */
204
    protected function registerHttpMiddlewares()
205
    {
206
        //referrer
207
        $this->pushMiddleware($this->headerMiddleware('Referer', $this->referrer), 'referrer');
208
    }
209
210
    /**
211
     * apply referrer to the request header
212
     * @param $header
213
     * @param $value
214
     * @return \Closure
215
     */
216
    function headerMiddleware($header, $value)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
217
    {
218
        return function (callable $handler) use ($header, $value) {
219
            return function (
220
                RequestInterface $request,
221
                array $options
222
            ) use ($handler, $header, $value) {
223
                $request = $request->withHeader($header, $value);
224
                return $handler($request, $options);
225
            };
226
        };
227
    }
228
}
229