Passed
Push — master ( 89a68d...f10cf1 )
by do
02:45
created

BaseClient::getMillisecond()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
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 0
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 2
rs 10
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 JinWeChat\Kernel\Contracts\CookiesInterface;
16
use JinWeChat\Kernel\Http\Response;
17
use JinWeChat\Kernel\Traits\HasHttpRequests;
18
use Psr\Http\Message\RequestInterface;
19
20
/**
21
 * Class BaseClient.
22
 *
23
 * @author docodeit <[email protected]>
24
 */
25
class BaseClient
26
{
27
    use HasHttpRequests {
28
        request as performRequest;
29
    }
30
31
    /**
32
     * @var \JinWeChat\Kernel\ServiceContainer
33
     */
34
    protected $app;
35
36
    /**
37
     * @var \JinWeChat\Kernel\Contracts\CookiesInterface
38
     */
39
    protected $cookies;
40
41
    /**
42
     * @var string
43
     */
44
    protected $referrer;
45
46
    /**
47
     * @var int
48
     */
49
    protected $token;
50
51
    /**
52
     * @var
53
     */
54
    protected $baseUri;
55
56
    /**
57
     * BaseClient constructor.
58
     *
59
     * @param \JinWeChat\Kernel\ServiceContainer                $app
60
     * @param \JinWeChat\Kernel\Contracts\CookiesInterface|null $cookies
61
     */
62
    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

62
    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...
63
    {
64
        $this->app = $app;
65
        $this->referrer = $app['config']->get('http.base_uri', 'https://mp.weixin.qq.com/');
66
        $this->token = isset($this->app->getConfig()['cookies']['token']) ? $this->app->getConfig()['cookies']['token'] : '';
0 ignored issues
show
Documentation Bug introduced by
It seems like IssetNode ? $this->app->...cookies']['token'] : '' can also be of type string. However, the property $token is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
67
    }
68
69
    /**
70
     * GET request.
71
     *
72
     * @param string $url
73
     * @param array  $query
74
     *
75
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
76
     *
77
     * @return \Psr\Http\Message\ResponseInterface
78
     */
79
    public function httpGet(string $url, array $query = [])
80
    {
81
        return $this->request($url, 'GET', $query);
82
    }
83
84
    /**
85
     * POST request.
86
     *
87
     * @param string $url
88
     * @param array  $data
89
     *
90
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
91
     *
92
     * @return \Psr\Http\Message\ResponseInterface
93
     */
94
    public function httpPost(string $url, array $data = [])
95
    {
96
        return $this->request($url, 'POST', ['form_params' => $data]);
97
    }
98
99
    /**
100
     * JSON request.
101
     *
102
     * @param string       $url
103
     * @param string|array $data
104
     * @param array        $query
105
     *
106
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
107
     *
108
     * @return \Psr\Http\Message\ResponseInterface
109
     */
110
    public function httpPostJson(string $url, array $data = [], array $query = [])
111
    {
112
        return $this->request($url, 'POST', ['query' => $query, 'json' => $data]);
113
    }
114
115
    /**
116
     * Upload file.
117
     *
118
     * @param string $url
119
     * @param array  $files
120
     * @param array  $form
121
     * @param array  $query
122
     *
123
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
124
     *
125
     * @return \Psr\Http\Message\ResponseInterface
126
     */
127
    public function httpUpload(string $url, array $files = [], array $form = [], array $query = [])
128
    {
129
        $multipart = [];
130
131
        foreach ($files as $name => $path) {
132
            $multipart[] = [
133
                'name' => $name,
134
                'contents' => fopen($path, 'r'),
135
            ];
136
        }
137
138
        foreach ($form as $name => $contents) {
139
            $multipart[] = compact('name', 'contents');
140
        }
141
142
        return $this->request($url, 'POST', ['query' => $query, 'multipart' => $multipart]);
143
    }
144
145
    /**
146
     * @param string $url
147
     * @param string $method
148
     * @param array  $options
149
     * @param bool   $returnRaw
150
     *
151
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
152
     *
153
     * @return \Psr\Http\Message\ResponseInterface
154
     */
155
    public function request(string $url, string $method = 'GET', array $options = [], $returnRaw = false)
156
    {
157
        if (empty($this->middlewares)) {
158
            $this->registerHttpMiddlewares();
159
        }
160
        //options 加入token
161
        if (isset($options['query'])) {
162
            $options['query'] = array_merge($options['query'], ['token' => $this->token]);
163
        }
164
        $response = $this->performRequest($url, $method, $options);
165
        //保存Token todo::改为缓存
166
        if (preg_match('/cgi-bin\/bizlogin?action=startlogin/', $url, $urlMatch)) {
167
            if (preg_match('/token=([\d]+)/i', $response['redirect_url'], $match)) {
168
                $this->token = $match[1];
169
            }
170
        }
171
172
        return $returnRaw ? $response : $this->castResponseToType($response, $this->app->config->get('response_type'));
173
    }
174
175
    /**
176
     * @param string $url
177
     * @param string $method
178
     * @param array  $options
179
     *
180
     * @throws \JinWeChat\Kernel\Exceptions\InvalidConfigException
181
     *
182
     * @return \JinWeChat\Kernel\Http\Response
183
     */
184
    public function requestRaw(string $url, string $method = 'GET', array $options = [])
185
    {
186
        return Response::buildFromPsrResponse($this->request($url, $method, $options, true));
187
    }
188
189
    /**
190
     * Return GuzzleHttp\Client instance.
191
     *
192
     * @return \GuzzleHttp\Client
193
     */
194
    public function getHttpClient(): Client
195
    {
196
        if (!($this->httpClient instanceof Client)) {
197
            $this->httpClient = $this->app['http_client'] ?? new Client();
198
        }
199
200
        return $this->httpClient;
201
    }
202
203
    /**
204
     * Register Guzzle middlewares.
205
     */
206
    protected function registerHttpMiddlewares()
207
    {
208
        //referrer
209
        $this->pushMiddleware($this->headerMiddleware('Referer', $this->referrer), 'referrer');
210
    }
211
212
    /**
213
     * apply referrer to the request header.
214
     *
215
     * @param $header
216
     * @param $value
217
     *
218
     * @return \Closure
219
     */
220
    public function headerMiddleware($header, $value)
221
    {
222
        return function (callable $handler) use ($header, $value) {
223
            return function (
224
                RequestInterface $request,
225
                array $options
226
            ) use (
227
                $handler,
228
                $header,
229
                $value
230
            ) {
231
                $request = $request->withHeader($header, $value);
232
233
                return $handler($request, $options);
234
            };
235
        };
236
    }
237
238
    /**
239
     * 保存Cookies todo::保存到Cache.
240
     */
241
    public function saveCookies()
242
    {
243
        $cookies = $this->app['http_client']->getConfig()['cookies'];
0 ignored issues
show
Unused Code introduced by
The assignment to $cookies is dead and can be removed.
Loading history...
244
    }
245
246
    /**
247
     * 获取微秒
248
     * @return float
249
     */
250
    function getMillisecond()
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...
251
    {
252
        list($s1, $s2) = explode(' ', microtime());
253
        return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
254
    }
255
}
256