Base::setConfig()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace tinymeng\Chinaums\Service\Common;
4
5
use Exception;
6
use tinymeng\Chinaums\Exception\TException;
7
use tinymeng\Chinaums\Tools\Http;
8
use tinymeng\tools\FileTool;
9
10
/**
11
 * Base
12
 * @method static \tinymeng\Chinaums\Service\Common\Base request(array $params) 创建请求
13
 */
14
class Base
15
{
16
    /**
17
     * @var array $config 网关
18
     */
19
    protected $config = [];
20
21
    protected $gateway;
22
    protected $gateway_type = 'default';
23
24
    /**
25
     * @var string 接口地址
26
     */
27
    protected $api;
28
    /**
29
     * @var array $body 请求参数
30
     */
31
    protected $body;
32
    /**
33
     * 代码传输过来的请求参数
34
     * @var
35
     */
36
    protected $params;
37
    /**
38
     * 必传的值
39
     * @var array
40
     */
41
    protected $require = [];
42
43
    /**
44
     * @param $config
45
     * @param $params
46
     */
47
    public function __construct($config=[],$params=[])
48
    {
49
        if(!empty($config)){
50
            $this->config = $config;
51
            $this->loadConfigGateway();
52
        }
53
        $this->params = $params;
54
    }
55
56
    /**
57
     * 加载多网关
58
     * @return Base
59
     */
60
    private function loadConfigGateway()
61
    {
62
        $gateway = $this->config['gateway'];// 正式环境
63
        if($this->config['sandbox'] === false){
64
            $this->gateway = isset($gateway[$this->gateway_type]) ? $gateway[$this->gateway_type] : $gateway['default'];// 沙箱环境
65
        }else{
66
            $this->gateway = $gateway['sandbox'];// 沙箱环境
67
        }
68
69
        return $this;
70
    }
71
72
    /**
73
     * @return false|string
74
     * @throws Exception
75
     */
76
    private function loadData()
77
    {
78
        $data = $this->params;
79
        $data['mid'] = $this->config['mid'];
80
        $data['tid'] = $this->config['tid'];
81
        $data['requestTimestamp'] = date("YmdHis", time());
82
        if ($data) {
83
            $this->body = array_merge($this->body, $data);
84
        }
85
        $this->validate();
86
        $data = $this->body;
87
        $data = json_encode($data);
88
        return $data;
89
    }
90
91
    /**
92
     * @return false|mixed|string
93
     */
94
    public function request($params = [])
95
    {
96
        if(!empty($params)){
97
            $this->params = $params;
98
        }
99
100
        try {
101
            $data = $this->loadData();
102
            $sign = $this->generateSign($data);
103
            $gateway  = $this->gateway . $this->api;
104
105
            if ('cli' == php_sapi_name()) {
106
                echo 'api:' . $gateway . PHP_EOL;
107
                echo 'request:' . $data . PHP_EOL;
108
            }
109
            $headers = [
110
                'Content-Type: application/json',
111
                'Content-Length: ' . strlen($data),
112
                'Authorization: ' . $sign
113
            ];
114
            $options = [
115
                CURLOPT_HTTPHEADER => $headers,
116
                CURLOPT_TIMEOUT => 60,
117
                CURLOPT_CONNECTTIMEOUT => 30
118
            ];
119
            $response = Http::post($gateway, $data, $options);
0 ignored issues
show
Bug introduced by
$data of type string is incompatible with the type array expected by parameter $params of tinymeng\Chinaums\Tools\Http::post(). ( Ignorable by Annotation )

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

119
            $response = Http::post($gateway, /** @scrutinizer ignore-type */ $data, $options);
Loading history...
120
            $this->writeLog('Request url:'.$gateway.PHP_EOL.'params:'.json_encode($data).PHP_EOL.'options:'.json_encode($options).PHP_EOL.'response'.$response);
121
            return $response;
122
        } catch (Exception $e) {
123
            if ('cli' == php_sapi_name()) {
124
                echo $e->getMessage() . PHP_EOL;
125
            }
126
            throw new TException("Chinaums request error:".$e->getMessage());
127
        }
128
    }
129
130
    /**
131
     * @return string
132
     */
133
    public function formRequest()
134
    {
135
        try {
136
            $data = $this->loadData();
137
            $params = $this->generateSign($data,true);
138
            $gateway  = $this->gateway . $this->api;
139
140
            $data = json_encode($data);
141
            if ('cli' == php_sapi_name()) {
142
                echo 'api:' . $gateway . PHP_EOL;
143
                echo 'request:' . $data . PHP_EOL;
144
            }
145
146
            $options = [
147
                CURLOPT_TIMEOUT => 60,
148
                CURLOPT_CONNECTTIMEOUT => 30
149
            ];
150
            $response = Http::get($gateway,$params,$options);
0 ignored issues
show
Bug introduced by
$params of type string is incompatible with the type array expected by parameter $params of tinymeng\Chinaums\Tools\Http::get(). ( Ignorable by Annotation )

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

150
            $response = Http::get($gateway,/** @scrutinizer ignore-type */ $params,$options);
Loading history...
151
            $this->writeLog('formRequest url:'.$gateway.PHP_EOL.'params:'.json_encode($data).PHP_EOL.'options:'.json_encode($options).PHP_EOL.'response'.$response);
152
            return $response;
153
        } catch (Exception $e) {
154
            throw new TException("Chinaums formRequest error:".$e->getMessage());
155
        }
156
    }
157
158
    /**
159
     * @param $config
160
     * @return $this
161
     */
162
    public function setConfig($config)
163
    {
164
        $this->config = $config;
165
        $this->loadConfigGateway();
166
        return $this;
167
    }
168
169
    /**
170
     * @param $value
171
     * @return $this
172
     */
173
    public function setBody($value)
174
    {
175
        $this->body = array_merge($this->body, $value);
176
        return $this;
177
    }
178
179
    /**
180
     * @return true
181
     * @throws Exception
182
     */
183
    protected function validate()
184
    {
185
        $require = $this->require;
186
        $key = array_keys($this->body);
187
188
        foreach ($require as $v) {
189
            if (!in_array($v, $key)) {
190
                throw new Exception($v . ' is require!!');
191
            }
192
        }
193
        return true;
194
    }
195
    /**
196
     * 根绝类型生成sign
197
     * @param $params
198
     * @param string $signType
199
     * @return string
200
     */
201
    public function generateSign($body,$openForm=false)
202
    {
203
        $body = (!is_string($body)) ? json_encode($body) : $body;
204
        $appid = $this->config['appid'];
205
        $appkey = $this->config['appkey'];
206
        $timestamp = date("YmdHis", time());
207
        $nonce = md5(uniqid(microtime(true), true));
208
        $str = bin2hex(hash('sha256', $body, true));
209
        $signature = base64_encode(hash_hmac('sha256', "$appid$timestamp$nonce$str", $appkey, true));
210
        $authorization = "OPEN-BODY-SIG AppId=\"$appid\", Timestamp=\"$timestamp\", Nonce=\"$nonce\", Signature=\"$signature\"";
211
        if($openForm){
212
            $params = [
213
                'appId'=>$appid,
214
                'timestamp'=>$timestamp,
215
                'nonce'=>$nonce,
216
                'content'=>$body,
217
                'signature'=>$signature,
218
                'authorization'=>'OPEN-FORM-PARAM',
219
            ];
220
            return $params;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $params returns the type array<string,mixed|string> which is incompatible with the documented return type string.
Loading history...
221
        }
222
        return $authorization;
223
    }
224
225
    /**
226
     * @param $name
227
     * @param $value
228
     * @return void
229
     */
230
    public function __set($name, $value)
231
    {
232
        $this->body[$name] = $value;
233
    }
234
235
    /**
236
     * @param $message
237
     * @param $file_name
238
     * @return void
239
     */
240
    private function writeLog($message,$file_name = 'chinaums')
241
    {
242
        FileTool::writeLog($message,$file_name);
243
    }
244
}
245