Passed
Push — v6 ( 95b370...25ce72 )
by 光春
03:13
created

DingTalkClient::logCommunicationError()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 14
c 1
b 0
f 0
nc 2
nop 4
dl 0
loc 17
rs 9.7998
1
<?php
2
class DingTalkClient
3
{
4
	/**@Author chaohui.zch copy from TopClient and modify 2016-12-14 **/
5
6
    /**@Author chaohui.zch modify $gatewayUrl 2017-07-18 **/
7
    public $gatewayUrl = "https://eco.taobao.com/router/rest";
8
9
	public $format = "xml";
10
11
	public $connectTimeout;
12
13
	public $readTimeout;
14
15
    public $apiCallType;
16
17
    public $httpMethod;
18
19
	/** 是否打开入参check**/
20
	public $checkRequest = true;
21
22
	protected $apiVersion = "2.0";
23
24
	protected $sdkVersion = "dingtalk-sdk-php-20161214";
25
26
    public function __construct($apiCallType = null, $httpMethod = null, $format = "xml"){
27
        $this->apiCallType = $apiCallType;
28
        $this->httpMethod = $httpMethod;
29
        $this->format = $format;
30
    }
31
32
	public function curl($url, $postFields = null)
33
	{
34
		$ch = curl_init();
35
		curl_setopt($ch, CURLOPT_URL, $url);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

35
		curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_URL, $url);
Loading history...
36
		curl_setopt($ch, CURLOPT_FAILONERROR, false);
37
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
38
		if ($this->readTimeout) {
39
			curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
40
		}
41
		if ($this->connectTimeout) {
42
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
43
		}
44
		curl_setopt ( $ch, CURLOPT_USERAGENT, "dingtalk-sdk-php" );
45
		//https 请求
46
		if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
47
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
48
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
49
		}
50
51
		if (is_array($postFields) && 0 < count($postFields))
52
		{
53
			$postBodyString = "";
54
			$postMultipart = false;
55
			foreach ($postFields as $k => $v)
56
			{
57
				if("@" != substr($v, 0, 1))//判断是不是文件上传
58
				{
59
					$postBodyString .= "$k=" . urlencode($v) . "&"; 
60
				}
61
				else//文件上传用multipart/form-data,否则用www-form-urlencoded
62
				{
63
					$postMultipart = true;
64
					if(class_exists('\CURLFile')){
65
						$postFields[$k] = new \CURLFile(substr($v, 1));
66
					}
67
				}
68
			}
69
			unset($k, $v);
70
			curl_setopt($ch, CURLOPT_POST, true);
71
			if ($postMultipart)
72
			{
73
				if (class_exists('\CURLFile')) {
74
				    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
75
				} else {
76
				    if (defined('CURLOPT_SAFE_UPLOAD')) {
77
				        curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
78
				    }
79
				}
80
				curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
81
			}
82
			else
83
			{
84
				$header = array("content-type: application/x-www-form-urlencoded; charset=UTF-8");
85
				curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
86
				curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString,0,-1));
87
			}
88
		}
89
		$reponse = curl_exec($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

89
		$reponse = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
90
		
91
		if (curl_errno($ch))
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_errno() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

91
		if (curl_errno(/** @scrutinizer ignore-type */ $ch))
Loading history...
92
		{
93
			throw new Exception(curl_error($ch),0);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

93
			throw new Exception(curl_error(/** @scrutinizer ignore-type */ $ch),0);
Loading history...
94
		}
95
		else
96
		{
97
			$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

97
			$httpStatusCode = curl_getinfo(/** @scrutinizer ignore-type */ $ch, CURLINFO_HTTP_CODE);
Loading history...
98
			if (200 !== $httpStatusCode)
99
			{
100
				throw new Exception($reponse,$httpStatusCode);
101
			}
102
		}
103
		curl_close($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

103
		curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
104
		return $reponse;
105
	}
106
107
    public function curl_get($url,$apiFields = null)
108
    {
109
        $ch = curl_init();
110
111
        foreach ($apiFields as $key => $value)
112
        {
113
            $url .= "&" ."$key=" . urlencode($value);
114
        }
115
116
        curl_setopt($ch, CURLOPT_URL, $url);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

116
        curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_URL, $url);
Loading history...
117
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
118
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
119
        curl_setopt($ch, CURLOPT_HEADER, false);
120
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
121
122
123
        if ($this->readTimeout)
124
        {
125
            curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
126
        }
127
128
        if ($this->connectTimeout)
129
        {
130
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
131
        }
132
133
        curl_setopt ( $ch, CURLOPT_USERAGENT, "dingtalk-sdk-php" );
134
135
        //https ignore ssl check ?
136
        if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" )
137
        {
138
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
139
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
140
        }
141
142
        $reponse = curl_exec($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

142
        $reponse = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
143
144
        if (curl_errno($ch))
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_errno() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

144
        if (curl_errno(/** @scrutinizer ignore-type */ $ch))
Loading history...
145
        {
146
            throw new Exception(curl_error($ch),0);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

146
            throw new Exception(curl_error(/** @scrutinizer ignore-type */ $ch),0);
Loading history...
147
        }
148
        else
149
        {
150
            $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

150
            $httpStatusCode = curl_getinfo(/** @scrutinizer ignore-type */ $ch, CURLINFO_HTTP_CODE);
Loading history...
151
            if (200 !== $httpStatusCode)
152
            {
153
                throw new Exception($reponse,$httpStatusCode);
154
            }
155
        }
156
        curl_close($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

156
        curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
157
        return $reponse;
158
    }
159
160
    public function curl_json($url, $postFields = null)
161
    {
162
        $ch = curl_init();
163
        curl_setopt($ch, CURLOPT_URL, $url);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

163
        curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_URL, $url);
Loading history...
164
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
165
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
166
        if ($this->readTimeout) {
167
            curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
168
        }
169
        if ($this->connectTimeout) {
170
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
171
        }
172
        curl_setopt ( $ch, CURLOPT_USERAGENT, "dingtalk-sdk-php" );
173
        //https 请求
174
        if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
175
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
176
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
177
        }
178
179
        if (is_array($postFields) && 0 < count($postFields))
180
        {
181
            $postBodyString = "";
182
            $postMultipart = false;
183
            foreach ($postFields as $k => $v)
184
            {
185
                if(!is_string($v)){
186
                    $v = json_encode($v);
187
                }
188
                if("@" != substr($v, 0, 1))//判断是不是文件上传
189
                {
190
                    $postBodyString .= "$k=" . urlencode($v) . "&";
191
                }
192
                else//文件上传用multipart/form-data,否则用www-form-urlencoded
193
                {
194
                    $postMultipart = true;
195
                    if(class_exists('\CURLFile')){
196
                        $postFields[$k] = new \CURLFile(substr($v, 1));
197
                    }
198
                }
199
            }
200
            unset($k, $v);
201
            curl_setopt($ch, CURLOPT_POST, true);
202
            if ($postMultipart)
203
            {
204
                if (class_exists('\CURLFile')) {
205
                    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
206
                } else {
207
                    if (defined('CURLOPT_SAFE_UPLOAD')) {
208
                        curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
209
                    }
210
                }
211
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
212
            }
213
            else {
214
                $header = array("Content-Type: application/json; charset=utf-8", "Content-Length:".strlen(json_encode($postFields)));
215
                curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
216
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
217
            }
218
        }
219
        $reponse = curl_exec($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

219
        $reponse = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
220
221
        if (curl_errno($ch))
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_errno() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

221
        if (curl_errno(/** @scrutinizer ignore-type */ $ch))
Loading history...
222
        {
223
            throw new Exception(curl_error($ch),0);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

223
            throw new Exception(curl_error(/** @scrutinizer ignore-type */ $ch),0);
Loading history...
224
        }
225
        else
226
        {
227
            $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

227
            $httpStatusCode = curl_getinfo(/** @scrutinizer ignore-type */ $ch, CURLINFO_HTTP_CODE);
Loading history...
228
            if (200 !== $httpStatusCode)
229
            {
230
                throw new Exception($reponse,$httpStatusCode);
231
            }
232
        }
233
        curl_close($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

233
        curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
234
        return $reponse;
235
    }
236
237
	public function curl_with_memory_file($url, $postFields = null, $fileFields = null)
238
	{
239
		$ch = curl_init();
240
		curl_setopt($ch, CURLOPT_URL, $url);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

240
		curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_URL, $url);
Loading history...
241
		curl_setopt($ch, CURLOPT_FAILONERROR, false);
242
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
243
		if ($this->readTimeout) {
244
			curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
245
		}
246
		if ($this->connectTimeout) {
247
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
248
		}
249
		curl_setopt ( $ch, CURLOPT_USERAGENT, "dingtalk-sdk-php" );
250
		//https 请求
251
		if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
252
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
253
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
254
		}
255
		//生成分隔符
256
		$delimiter = '-------------' . uniqid();
257
		//先将post的普通数据生成主体字符串
258
		$data = '';
259
		if($postFields != null){
260
			foreach ($postFields as $name => $content) {
261
			    $data .= "--" . $delimiter . "\r\n";
262
			    $data .= 'Content-Disposition: form-data; name="' . $name . '"';
263
			    //multipart/form-data 不需要urlencode,参见 http:stackoverflow.com/questions/6603928/should-i-url-encode-post-data
264
			    $data .= "\r\n\r\n" . $content . "\r\n";
265
			}
266
			unset($name,$content);
267
		}
268
269
		//将上传的文件生成主体字符串
270
		if($fileFields != null){
271
			foreach ($fileFields as $name => $file) {
272
			    $data .= "--" . $delimiter . "\r\n";
273
			    $data .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $file['filename'] . "\" \r\n";
274
			    $data .= 'Content-Type: ' . $file['type'] . "\r\n\r\n";//多了个文档类型
275
276
			    $data .= $file['content'] . "\r\n";
277
			}
278
			unset($name,$file);
279
		}
280
		//主体结束的分隔符
281
		$data .= "--" . $delimiter . "--";
282
283
		curl_setopt($ch, CURLOPT_POST, true);
284
		curl_setopt($ch, CURLOPT_HTTPHEADER , array(
285
		    'Content-Type: multipart/form-data; boundary=' . $delimiter,
286
		    'Content-Length: ' . strlen($data))
287
		); 
288
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
289
		curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
290
291
		$reponse = curl_exec($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

291
		$reponse = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
292
		unset($data);
293
294
		if (curl_errno($ch))
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_errno() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

294
		if (curl_errno(/** @scrutinizer ignore-type */ $ch))
Loading history...
295
		{
296
			throw new Exception(curl_error($ch),0);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

296
			throw new Exception(curl_error(/** @scrutinizer ignore-type */ $ch),0);
Loading history...
297
		}
298
		else
299
		{
300
			$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

300
			$httpStatusCode = curl_getinfo(/** @scrutinizer ignore-type */ $ch, CURLINFO_HTTP_CODE);
Loading history...
301
			if (200 !== $httpStatusCode)
302
			{
303
				throw new Exception($reponse,$httpStatusCode);
304
			}
305
		}
306
		curl_close($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

306
		curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
307
		return $reponse;
308
	}
309
310
	protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt)
311
	{
312
		$localIp = isset($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI";
313
		$logger = new TopLogger;
314
		$logger->conf["log_file"] = rtrim(TOP_SDK_WORK_DIR, '\\/') . '/' . "logs/top_comm_err_" . "_" . date("Y-m-d") . ".log";
315
		$logger->conf["separator"] = "^_^";
316
		$logData = array(
317
		date("Y-m-d H:i:s"),
318
		$apiName,
319
		$localIp,
320
		PHP_OS,
321
		$this->sdkVersion,
322
		$requestUrl,
323
		$errorCode,
324
		str_replace("\n","",$responseTxt)
325
		);
326
		$logger->log($logData);
327
	}
328
329
    public function execute($request, $session = null,$bestUrl = null){
330
        if(DingTalkConstant::$CALL_TYPE_OAPI == $this->apiCallType){
331
            return $this->_executeOapi($request, $session, $bestUrl, null, null, null, null);
332
        }else{
333
            return $this->_execute($request, $session, $bestUrl);
334
        }
335
    }
336
337
    public function executeWithAccessKey($request, $bestUrl = null, $accessKey, $accessSecret){
338
        return $this->executeWithCorpId($request, $bestUrl, $accessKey, $accessSecret, null, null);
339
    }
340
341
    public function executeWithSuiteTicket($request,$bestUrl = null, $accessKey, $accessSecret, $suiteTicket){
342
        return $this->executeWithCorpId($request,$bestUrl, $accessKey, $accessSecret, $suiteTicket, null);
343
    }
344
345
	public function executeWithCorpId($request, $bestUrl = null, $accessKey, $accessSecret, $suiteTicket, $corpId) {
346
        if(DingTalkConstant::$CALL_TYPE_OAPI == $this->apiCallType){
347
            return $this->_executeOapi($request, null, $bestUrl,$accessKey, $accessSecret, $suiteTicket, $corpId);
348
        }else{
349
            return $this->_execute($request, null, $bestUrl);
350
        }
351
    }
352
353
    private function _executeOapi($request, $session = null,$bestUrl = null,$accessKey, $accessSecret, $suiteTicket, $corpId){
354
        $result =  new ResultSet();
355
        if($this->checkRequest) {
356
            try {
357
                $request->check();
358
            } catch (Exception $e) {
359
360
                $result->code = $e->getCode();
361
                $result->msg = $e->getMessage();
362
                return $result;
363
            }
364
        }
365
366
        $sysParams["method"] = $request->getApiMethodName();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$sysParams was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sysParams = array(); before regardless.
Loading history...
367
        //系统参数放入GET请求串
368
        if($bestUrl){
369
            if(strpos($bestUrl,'?') === false){
370
                $requestUrl = $bestUrl."?";
371
            }else{
372
                $requestUrl = $bestUrl;
373
            }
374
        }else{
375
            $requestUrl = $this->gatewayUrl."?";
376
        }
377
        if(null != $accessKey){
378
            $timestamp = $this->getMillisecond();
379
            // 验证签名有效性
380
            $canonicalString = $this->getCanonicalStringForIsv($timestamp, $suiteTicket);
381
            $signature = $this->computeSignature($accessSecret, $canonicalString);
382
383
            $queryParams["accessKey"] = $accessKey;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$queryParams was never initialized. Although not strictly required by PHP, it is generally a good practice to add $queryParams = array(); before regardless.
Loading history...
384
            $queryParams["signature"] = $signature;
385
            $queryParams["timestamp"] = $timestamp+"";
386
            if($suiteTicket != null) {
387
                $queryParams["suiteTicket"] = $suiteTicket;
388
            }
389
            if($corpId != null){
390
                $queryParams["corpId"] =  $corpId;
391
            }
392
            foreach ($queryParams as $queryParamKey => $queryParamValue) {
393
                $requestUrl .= "$queryParamKey=" . urlencode($queryParamValue) . "&";
394
            }
395
        }else{
396
            $requestUrl .= "access_token=" . urlencode($session) . "&";
397
        }
398
399
        $apiParams = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $apiParams is dead and can be removed.
Loading history...
400
        //获取业务参数
401
        $apiParams = $request->getApiParas();
402
        $fileFields = array();
403
        foreach ($apiParams as $key => $value) {
404
            if(is_array($value) && array_key_exists('type',$value) && array_key_exists('content',$value) ){
405
                $value['name'] = $key;
406
                $fileFields[$key] = $value;
407
                unset($apiParams[$key]);
408
            }
409
        }
410
411
        // $requestUrl .= "timestamp=" . urlencode($sysParams["timestamp"]) . "&";
412
        $requestUrl = substr($requestUrl, 0, -1);
413
414
        //发起HTTP请求
415
        try
416
        {
417
            if(count($fileFields) > 0){
418
                $resp = $this->curl_with_memory_file($requestUrl, $apiParams, $fileFields);
419
            }else{
420
                if(DingTalkConstant::$METHOD_POST == $this->httpMethod){
421
                    $resp = $this->curl_json($requestUrl, $apiParams);
422
                }else{
423
                    $resp = $this->curl_get($requestUrl, $apiParams);
424
                }
425
            }
426
        }
427
        catch (Exception $e)
428
        {
429
            $this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_ERROR_" . $e->getCode(),$e->getMessage());
430
            $result->code = $e->getCode();
431
            $result->msg = $e->getMessage();
432
            return $result;
433
        }
434
435
        unset($apiParams);
436
        unset($fileFields);
437
        //解析TOP返回结果
438
        $respWellFormed = false;
439
        if ("json" == $this->format)
440
        {
441
            $respObject = json_decode($resp);
442
            if (null !== $respObject)
443
            {
444
                $respWellFormed = true;
445
            }
446
        }
447
        else if("xml" == $this->format)
448
        {
449
            $respObject = @simplexml_load_string($resp);
450
            if (false !== $respObject)
451
            {
452
                $respWellFormed = true;
453
            }
454
        }
455
456
        //返回的HTTP文本不是标准JSON或者XML,记下错误日志
457
        if (false === $respWellFormed)
458
        {
459
            $this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_RESPONSE_NOT_WELL_FORMED",$resp);
460
            $result->code = 0;
461
            $result->msg = "HTTP_RESPONSE_NOT_WELL_FORMED";
462
            return $result;
463
        }
464
465
        //如果TOP返回了错误码,记录到业务错误日志中
466
        if (isset($respObject->code))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $respObject does not seem to be defined for all execution paths leading up to this point.
Loading history...
467
        {
468
            $logger = new TopLogger;
469
            $logger->conf["log_file"] = rtrim(TOP_SDK_WORK_DIR, '\\/') . '/' . "logs/top_biz_err_" .  "_" . date("Y-m-d") . ".log";
470
            $logger->log(array(
471
                date("Y-m-d H:i:s"),
472
                $resp
473
            ));
474
        }
475
        return $respObject;
476
    }
477
478
    private function getMillisecond() {
479
        list($s1, $s2) = explode(' ', microtime());
480
        return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
481
    }
482
483
    private function getCanonicalStringForIsv($timestamp, $suiteTicket) {
484
        $result = $timestamp;
485
        if($suiteTicket != null) {
486
            $result .= "\n".$suiteTicket;
487
        }
488
        return $result;
489
    }
490
491
    private function computeSignature($accessSecret, $canonicalString){
492
        $s = hash_hmac('sha256', $canonicalString, $accessSecret, true);
493
        return base64_encode($s);
494
    }
495
496
    private function _execute($request, $session = null,$bestUrl = null)
497
	{
498
		$result =  new ResultSet(); 
499
		if($this->checkRequest) {
500
			try {
501
				$request->check();
502
			} catch (Exception $e) {
503
504
				$result->code = $e->getCode();
505
				$result->msg = $e->getMessage();
506
				return $result;
507
			}
508
		}
509
		//组装系统参数
510
		$sysParams["v"] = $this->apiVersion;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$sysParams was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sysParams = array(); before regardless.
Loading history...
511
		$sysParams["format"] = $this->format;
512
		$sysParams["method"] = $request->getApiMethodName();
513
		$sysParams["timestamp"] = date("Y-m-d H:i:s");
514
		if (null != $session)
515
		{
516
			$sysParams["session"] = $session;
517
		}
518
		$apiParams = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $apiParams is dead and can be removed.
Loading history...
519
		//获取业务参数
520
		$apiParams = $request->getApiParas();
521
522
523
		//系统参数放入GET请求串
524
		if($bestUrl){
525
            if(strpos($bestUrl,'?') === false){
526
                $requestUrl = $bestUrl."?";
527
            }else{
528
                $requestUrl = $bestUrl;
529
            }
530
			$sysParams["partner_id"] = $this->getClusterTag();
531
		}else{
532
			$requestUrl = $this->gatewayUrl."?";
533
			$sysParams["partner_id"] = $this->sdkVersion;
534
		}
535
536
		foreach ($sysParams as $sysParamKey => $sysParamValue)
537
		{
538
			// if(strcmp($sysParamKey,"timestamp") != 0)
539
			$requestUrl .= "$sysParamKey=" . urlencode($sysParamValue) . "&";
540
		}
541
542
		$fileFields = array();
543
		foreach ($apiParams as $key => $value) {
544
			if(is_array($value) && array_key_exists('type',$value) && array_key_exists('content',$value) ){
545
				$value['name'] = $key;
546
				$fileFields[$key] = $value;
547
				unset($apiParams[$key]);
548
			}
549
		}
550
551
		// $requestUrl .= "timestamp=" . urlencode($sysParams["timestamp"]) . "&";
552
		$requestUrl = substr($requestUrl, 0, -1);
553
554
		//发起HTTP请求
555
		try
556
		{
557
			if(count($fileFields) > 0){
558
				$resp = $this->curl_with_memory_file($requestUrl, $apiParams, $fileFields);
559
			}else{
560
				$resp = $this->curl($requestUrl, $apiParams);
561
			}
562
		}
563
		catch (Exception $e)
564
		{
565
			$this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_ERROR_" . $e->getCode(),$e->getMessage());
566
			$result->code = $e->getCode();
567
			$result->msg = $e->getMessage();
568
			return $result;
569
		}
570
571
		unset($apiParams);
572
		unset($fileFields);
573
		//解析TOP返回结果
574
		$respWellFormed = false;
575
		if ("json" == $this->format)
576
		{
577
			$respObject = json_decode($resp);
578
			if (null !== $respObject)
579
			{
580
				$respWellFormed = true;
581
				foreach ($respObject as $propKey => $propValue)
582
				{
583
					$respObject = $propValue;
584
				}
585
			}
586
		}
587
		else if("xml" == $this->format)
588
		{
589
			$respObject = @simplexml_load_string($resp);
590
			if (false !== $respObject)
591
			{
592
				$respWellFormed = true;
593
			}
594
		}
595
596
		//返回的HTTP文本不是标准JSON或者XML,记下错误日志
597
		if (false === $respWellFormed)
598
		{
599
			$this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_RESPONSE_NOT_WELL_FORMED",$resp);
600
			$result->code = 0;
601
			$result->msg = "HTTP_RESPONSE_NOT_WELL_FORMED";
602
			return $result;
603
		}
604
605
		//如果TOP返回了错误码,记录到业务错误日志中
606
		if (isset($respObject->code))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $respObject does not seem to be defined for all execution paths leading up to this point.
Loading history...
607
		{
608
			$logger = new TopLogger;
609
			$logger->conf["log_file"] = rtrim(TOP_SDK_WORK_DIR, '\\/') . '/' . "logs/top_biz_err_" .  "_" . date("Y-m-d") . ".log";
610
			$logger->log(array(
611
				date("Y-m-d H:i:s"),
612
				$resp
613
			));
614
		}
615
		return $respObject;
616
	}
617
618
	public function exec($paramsArray)
619
	{
620
		if (!isset($paramsArray["method"]))
621
		{
622
			trigger_error("No api name passed");
623
		}
624
		$inflector = new LtInflector;
0 ignored issues
show
Bug introduced by
The type LtInflector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
625
		$inflector->conf["separator"] = ".";
626
		$requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request";
627
		if (!class_exists($requestClassName))
628
		{
629
			trigger_error("No such dingtalk-api: " . $paramsArray["method"]);
630
		}
631
632
		$session = isset($paramsArray["session"]) ? $paramsArray["session"] : null;
633
634
		$req = new $requestClassName;
635
		foreach($paramsArray as $paraKey => $paraValue)
636
		{
637
			$inflector->conf["separator"] = "_";
638
			$setterMethodName = $inflector->camelize($paraKey);
639
			$inflector->conf["separator"] = ".";
640
			$setterMethodName = "set" . $inflector->camelize($setterMethodName);
641
			if (method_exists($req, $setterMethodName))
642
			{
643
				$req->$setterMethodName($paraValue);
644
			}
645
		}
646
		return $this->execute($req, $session);
647
	}
648
649
	private function getClusterTag()
650
    {
651
	    return substr($this->sdkVersion,0,11)."-cluster".substr($this->sdkVersion,11);
652
    }
653
}
654