Passed
Push — master ( 21a6a4...4428d0 )
by xiaohui
03:17
created

ManageClient::getAuthorization()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 3
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
namespace AliMedia\Core;
3
4
use AliMedia\Utils\ManageOption;
5
use AliMedia\Utils\MediaResOption;
6
use AliMedia\Conf\Conf;
7
use AliMedia\Utils\ResourceInfo;
8
use AliMedia\Utils\EncodeUtils;
9
use Exception;
10
11
class ManageClient
12
{
13
    private $manage_host;
14
    private $ak;
15
    private $sk;
16
    private $type;
17
    public function __construct($ak, $sk, $type = Conf::TYPE_TOP)
18
    {
19
        $this->ak = $ak;
20
        $this->sk = $sk;
21
        $this->type = $type;
22
        $this->manage_host = Conf::MANAGE_HOST_MEDIA;
23
    }
24
25
    /**
26
     * 文件是否存在
27
     * @param string $namespace 空间名,必须
28
     * @param string $dir 路径
29
     * @param string $filename 文件名
30
     * @return array
31
     */
32
    public function existsFile($namespace, $dir, $filename)
33
    {
34
        $resourceInfo = new ResourceInfo($namespace, $dir, $filename);
35
        list($isValid, $message) = $resourceInfo->checkResourceInfo(true, true);
36
        if (!$isValid) {
37
            return $this->errorResponse("InvalidArgument", $message);
38
        }
39
        $resourceId = $resourceInfo->buildResourceId(); //得到资源ID
40
        $uri = '/' . Conf::MANAGE_API_VERSION . '/files/' . $resourceId . '/exist';
41
        return $this->sendRequest('GET', $uri);
42
    }
43
44
    /**
45
     * 获取文件的元信息(meta信息)
46
     * @param string $namespace 空间名,必须
47
     * @param string $dir 路径
48
     * @param string $filename 文件名
49
     * @return array
50
     */
51
    public function getFileInfo($namespace, $dir, $filename)
52
    {
53
        $resourceInfo = new ResourceInfo($namespace, $dir, $filename);
54
        list($isValid, $message) = $resourceInfo->checkResourceInfo(true, true);
55
        if (!$isValid) {
56
            return $this->errorResponse("InvalidArgument", $message);
57
        }
58
        $resourceId = $resourceInfo->buildResourceId(); //得到资源ID
59
        $uri = '/' . Conf::MANAGE_API_VERSION . '/files/' . $resourceId;
60
        return $this->sendRequest('GET', $uri);
61
    }
62
63
    /**
64
     * 重命名文件
65
     * @param string $namespace 空间名,必须
66
     * @param string $dir 路径
67
     * @param string $filename 文件名
68
     * @param string $newDir 新的路径
69
     * @param string $newName 新的文件名
70
     * @return array
71
     */
72
    public function renameFile($namespace, $dir, $filename, $newDir, $newName)
73
    {
74
        $resourceInfo = new ResourceInfo($namespace, $dir, $filename); //老的资源
75
        list($isValid, $message) = $resourceInfo->checkResourceInfo(true, true);
76
        if (!$isValid) {
77
            return $this->errorResponse("InvalidArgument", $message);
78
        }
79
        $newResourceInfo = new ResourceInfo($namespace, $newDir, $newName); //新的资源
80
        list($isValid, $message) = $newResourceInfo->checkResourceInfo(true, true);
81
        if (!$isValid) {
82
            return $this->errorResponse("InvalidArgument", $message);
83
        }
84
        $resourceId = $resourceInfo->buildResourceId(); //老资源ID
85
        $newResourceId = $newResourceInfo->buildResourceId(); //新资源ID
86
        $uri = '/' . Conf::MANAGE_API_VERSION . '/files/' . $resourceId . "/rename/" . $newResourceId;
87
        return $this->sendRequest('POST', $uri);
88
    }
89
90
    /**
91
     * 获取指定目录下的文件列表
92
     * @param string $namespace 空间名,必须
93
     * @param string $dir 路径
94
     * @param number $page 页数
95
     * @param number $pageSize 每页显示的记录数
96
     */
97
    public function listFiles($namespace, $dir, $page = 1, $pageSize = 100)
98
    {
99
        $manageOption = new ManageOption($namespace);
100
        $manageOption->setDir($dir)->setCurrentPage($page)->setPageSize($pageSize);
101
        list($isValid, $message) = $manageOption->checkResourceInfo(true);
102
        if ($page <= 0 || $pageSize <= 0) {
103
            $isValid = false;
104
            $message = "Invalid parameters page or pageSize";
105
        }
106
        if (!$isValid) {
107
            return $this->errorResponse("InvalidArgument", $message);
108
        }
109
        $queryParas = $manageOption->buildListFilesParas(); //查询query参数
110
        $uri = '/' . Conf::MANAGE_API_VERSION . '/files?' . $queryParas;
111
        return $this->sendRequest('GET', $uri);
112
    }
113
114
    /**
115
     * 删除文件
116
     * @param string $namespace 空间名,必须
117
     * @param string $dir 路径
118
     * @param string $filename 文件名
119
     * @return array
120
     */
121
    public function deleteFile($namespace, $dir, $filename)
122
    {
123
        $resourceInfo = new ResourceInfo($namespace, $dir, $filename);
124
        list($isValid, $message) = $resourceInfo->checkResourceInfo(true, true);
125
        if (!$isValid) {
126
            return $this->errorResponse("InvalidArgument", $message);
127
        }
128
        $resourceId = $resourceInfo->buildResourceId(); //得到资源ID
129
        $uri = '/' . Conf::MANAGE_API_VERSION . '/files/' . $resourceId;
130
        return $this->sendRequest('DELETE', $uri);
131
    }
132
133
    /**
134
     * 文件夹是否存在
135
     * @param string $namespace 空间名,必须
136
     * @param string $dir 路径,即文件夹
137
     * @return array
138
     */
139
    public function existsFolder($namespace, $dir)
140
    {
141
        if (empty($namespace) || empty($dir)) {
142
            return $this->errorResponse("InvalidArgument", "namespace or dir is empty");
143
        }
144
        if (strpos($dir, '/') !== 0) {
145
            $dir = '/' . $dir;
146
        }
147
        $resourceInfo = new ResourceInfo($namespace, $dir);
148
        $resourceId = $resourceInfo->buildResourceId(); //得到资源ID
149
        $uri = '/' . Conf::MANAGE_API_VERSION . '/folders/' . $resourceId . '/exist';
150
        return $this->sendRequest('GET', $uri);
151
    }
152
153
    /**
154
     * 创建文件夹
155
     * @param string $namespace 空间名,必须
156
     * @param string $dir 路径,即文件夹
157
     * @return array
158
     */
159
    public function createDir($namespace, $dir)
160
    {
161
        if (empty($namespace) || empty($dir)) {
162
            return $this->errorResponse("InvalidArgument", "namespace or dir is empty");
163
        }
164
        if (strpos($dir, '/') !== 0) {
165
            $dir = '/' . $dir;
166
        }
167
        $resourceInfo = new ResourceInfo($namespace, $dir);
168
        $resourceId = $resourceInfo->buildResourceId(); //得到资源ID
169
        $uri = '/' . Conf::MANAGE_API_VERSION . '/folders/' . $resourceId;
170
        return $this->sendRequest('POST', $uri);
171
    }
172
173
    /**
174
     * 获取指定目录下的文件夹列表
175
     * @param string $namespace 空间名,必须
176
     * @param string $dir 路径,指定目录
177
     * @param number $page 页数
178
     * @param number $pageSize 每页显示的记录数
179
     */
180
    public function listDirs($namespace, $dir, $page = 1, $pageSize = 100)
181
    {
182
        $manageOption = new ManageOption($namespace);
183
        $manageOption->setDir($dir)->setCurrentPage($page)->setPageSize($pageSize);
184
        list($isValid, $message) = $manageOption->checkResourceInfo(true);
185
        if ($page <= 0 || $pageSize <= 0) {
186
            $isValid = false;
187
            $message = "Invalid parameters page or pageSize";
188
        }
189
        if (!$isValid) {
190
            return $this->errorResponse("InvalidArgument", $message);
191
        }
192
        $queryParas = $manageOption->buildListFilesParas(); //查询query参数
193
        $uri = '/' . Conf::MANAGE_API_VERSION . '/folders?' . $queryParas;
194
        return $this->sendRequest('GET', $uri);
195
    }
196
197
    /**
198
     * 删除文件夹
199
     * @param string $namespace 空间名,必须
200
     * @param string $dir 路径,即文件夹
201
     * @return array
202
     */
203
    public function deleteDir($namespace, $dir)
204
    {
205
        if (empty($namespace) || empty($dir)) {
206
            return $this->errorResponse("InvalidArgument", "namespace or dir is empty");
207
        }
208
        if (strpos($dir, '/') !== 0) {
209
            $dir = '/' . $dir;
210
        }
211
        $resourceInfo = new ResourceInfo($namespace, $dir);
212
        $resourceId = $resourceInfo->buildResourceId(); //得到资源ID
213
        $uri = '/' . Conf::MANAGE_API_VERSION . '/folders/' . $resourceId;
214
        return $this->sendRequest('DELETE', $uri);
215
    }
216
    /*######################################华丽的分界线#######################################*/
217
    /*#######################上面是文件或文件夹的管理,下面是特色服务接口########################*/
218
    /*########################################################################################*/
219
    /**黄图扫描接口
220
     * @param ManageOption $resInfos 待扫描图片资源
221
     * @return array
222
     */
223
    public function scanPorn(ManageOption $resInfos)
224
    {
225
        $uri = '/' . Conf::SCAN_PORN_VERSION . '/scanPorn';
226
        list($isValid, $message, $bodyArray) = $resInfos->checkFilesAndUrls(); //检测并得到黄图扫描所需参数
227
        if (!$isValid) {
228
            return $this->errorResponse("InvalidArgument", $message);
229
        }
230
        $httpBody = $this->createHttpBody($bodyArray); //http body字符串信息
231
        return $this->sendRequest('POST', $uri, $httpBody);
232
    }
233
234
    /**
235
     * 鉴黄反馈feedback接口
236
     * @param ManageOption $pornFbInfos 反馈信息
237
     * @return array
238
     */
239
    public function pornFeedback(ManageOption $pornFbInfos)
240
    {
241
        $uri = '/' . Conf::SCAN_PORN_VERSION . '/feedback';
242
        list($isValid, $message, $httpBody) = $pornFbInfos->checkPornFeedbackInfos();
243
        if (!$isValid) {
244
            return $this->errorResponse("InvalidArgument", $message);
245
        }
246
        return $this->sendRequest('POST', $uri, $httpBody);
247
    }
248
249
    /**
250
     * 多媒体(音视频)转码服务接口
251
     * @param MediaResOption $encodeOption 转码参数选项
252
     * @return array
253
     */
254
    public function mediaEncode(MediaResOption $encodeOption)
255
    {
256
        $uri = '/' . Conf::MEDIA_ENCODE_VERSION . '/mediaEncode';
257
        list($isValid, $message, $httpBody) = $encodeOption->checkOptionParameters();
258
        if (!$isValid) {
259
            return $this->errorResponse("InvalidArgument", $message);
260
        }
261
        return $this->sendRequest('POST', $uri, $httpBody);
262
    }
263
264
    /**
265
     * 多媒体转码任务查询接口
266
     * @param string $taskId 转码任务ID
267
     */
268
    public function mediaEncodeQuery($taskId)
269
    {
270
        if (empty($taskId)) {
271
            return $this->errorResponse("InvalidArgument", "taskId is empty");
272
        }
273
        $uri = '/' . Conf::MEDIA_ENCODE_VERSION . '/mediaEncodeResult/' . $taskId;
274
        return $this->sendRequest('GET', $uri);
275
    }
276
277
    /**
278
     * 视频截图接口
279
     * @param MediaResOption $snapshotOption 截图参数选项
280
     * @return array
281
     */
282
    public function videoSnapshot(MediaResOption $snapshotOption)
283
    {
284
        $uri = '/' . Conf::MANAGE_API_VERSION . '/snapshot';
285
        list($isValid, $message, $httpBody) = $snapshotOption->checkOptionParameters();
286
        if (!$isValid) {
287
            return $this->errorResponse("InvalidArgument", $message);
288
        }
289
        return $this->sendRequest('POST', $uri, $httpBody);
290
    }
291
292
    /**
293
     * 视频截图结果查询接口
294
     * @param string $taskId 转码任务ID
295
     */
296
    public function vSnapshotQuery($taskId)
297
    {
298
        if (empty($taskId)) {
299
            return $this->errorResponse("InvalidArgument", "taskId is empty");
300
        }
301
        $uri = '/' . Conf::MANAGE_API_VERSION . '/snapshotResult/' . $taskId;
302
        return $this->sendRequest('GET', $uri);
303
    }
304
305
    /**
306
     *
307
     * 广告图扫描接口(beta)
308
     * @param ManageOption $resInfos 待扫描图片资源
309
     * @return array
310
     */
311
    public function scanAdvertising(ManageOption $resInfos)
312
    {
313
        $uri = '/3.1/scanAdvertising';
314
        list($isValid, $message, $bodyArray) = $resInfos->checkFilesAndUrls(); //检测并得到广告图图扫描所需参数
315
        if (!$isValid) {
316
            return $this->errorResponse("InvalidArgument", $message);
317
        }
318
        $httpBody = $this->createHttpBody($bodyArray); //http body字符串信息
319
        return $this->sendRequest('POST', $uri, $httpBody);
320
    }
321
322
    /**
323
     * 调用curl利用http上传数据
324
     * @param string $method
325
     * @param string $uri
326
     * @param array $bodyArray
327
     * @param array $headers
328
     * @return array (isSuccess, ...)
329
     */
330
    protected function sendRequest($method, $uri, $httpBody = null, $headers = null)
331
    {
332
        $success = false;
333
        $result = null;
334
        //构建Http请求头
335
        $_headers = array('Expect:');
336
        $date = $this->currentMilliSecond(); //得到当前的时间戳,毫秒
337
        array_push($_headers, "Date: {$date}");
338
        $authorization = $this->_getAuthorization($uri, $date, $httpBody);  //Http的Body需要加入管理鉴权
0 ignored issues
show
Bug introduced by
The method _getAuthorization() does not exist on AliMedia\Core\ManageClient. Did you maybe mean getAuthorization()? ( Ignorable by Annotation )

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

338
        /** @scrutinizer ignore-call */ 
339
        $authorization = $this->_getAuthorization($uri, $date, $httpBody);  //Http的Body需要加入管理鉴权

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
339
        array_push($_headers, "Authorization: {$authorization}");
340
        array_push($_headers, "User-Agent: {$this->getUserAgent()}");
341
        if (!is_null($headers) && is_array($headers)) {
342
            foreach ($headers as $k => $v) {
343
                array_push($_headers, "{$k}: {$v}");
344
            }
345
        }
346
        $url = $this->getManageUrl($uri); //根据管理接口uri拼接成URL
347
        $ch = curl_init($url);
348
        try {
349
            //构建http请求体,并设置header部分属性
350
            $length = 0;
351
            if (!empty($httpBody)) {
352
                $length = @strlen($httpBody);
353
                curl_setopt($ch, CURLOPT_POSTFIELDS, $httpBody);
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

353
                curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_POSTFIELDS, $httpBody);
Loading history...
354
                array_push($_headers, "Content-Type: application/x-www-form-urlencoded");
355
            }
356
            array_push($_headers, "Content-Length: {$length}");
357
            curl_setopt($ch, CURLOPT_HEADER, 1);                            //设置头部
358
            curl_setopt($ch, CURLOPT_HTTPHEADER, $_headers);                //请求头
359
            curl_setopt($ch, CURLOPT_TIMEOUT, Conf::HTTP_TIMEOUT);      //超时时长
360
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);               //连接超时时长
361
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //成功,只返回结果,不自动输出任何内容。如果失败返回FALSE
362
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
363
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);           //自定义请求
364
            //设置请求方式(GET或POST等)
365
            if ($method == 'PUT' || $method == 'POST') {
366
                curl_setopt($ch, CURLOPT_POST, 1);
367
            } else {
368
                curl_setopt($ch, CURLOPT_POST, 0);
369
            }
370
            //执行请求,然后获取服务端返回
371
            $response = 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

371
            $response = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
372
            if ($response == false) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $response of type boolean|string against false; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
373
                $result = $this->errorResponse("curl error", "curl request failed");
374
                $result['errno'] = 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

374
                $result['errno'] = curl_errno(/** @scrutinizer ignore-type */ $ch); //错误码
Loading history...
375
            } else {
376
                //解析返回结果,并判断是否上传成功
377
                $http_code = 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

377
                $http_code = curl_getinfo(/** @scrutinizer ignore-type */ $ch, CURLINFO_HTTP_CODE);
Loading history...
378
                $success = ($http_code == 200) ? true : false;                  //判断是否上传成功
379
                $resStr = explode("\r\n\r\n", $response);
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type true; however, parameter $string of explode() does only seem to accept string, 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

379
                $resStr = explode("\r\n\r\n", /** @scrutinizer ignore-type */ $response);
Loading history...
380
                $resBody = isset($resStr[1]) ? $resStr[1] : '';
381
                $resArray = json_decode($resBody, true);                        //解析得到结果
382
                $result = (empty($resArray)) ? array() : $resArray;
383
            }
384
        } catch (Exception $e) {
385
            $success = false;
386
            $result = $this->errorResponse("HTTPRequestException#" . $e->getCode(), $e->getMessage());
387
        }
388
        curl_close($ch); //PHP5.3中不支持finally关键字。因此,为了兼容,这里取消finally
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

388
        curl_close(/** @scrutinizer ignore-type */ $ch); //PHP5.3中不支持finally关键字。因此,为了兼容,这里取消finally
Loading history...
389
        $result['isSuccess'] = $success;
390
        return $result;
391
    }
392
393
    /**
394
     * 根据$bodyArray构建http请求体。多个字段之间用&号分割
395
     */
396
    protected function createHttpBody($bodyArray)
397
    {
398
        $bodyStr = '';
399
        foreach ($bodyArray as $key => $value) {
400
            $bodyStr .= (empty($bodyStr) ? null : '&'); //添加分隔符
401
            $bodyStr .= "{$key}=" . urlencode($value);
402
        }
403
        return $bodyStr;
404
    }
405
406
    /**
407
     * UserAgent用户代理
408
     */
409
    protected function getUserAgent()
410
    {
411
        if ($this->type == "TOP") {
412
            return "ALIMEDIASDK_PHP_TAE/" . Conf::SDK_VERSION;
413
        } else {
414
            return "ALIMEDIASDK_PHP_CLOUD/" . Conf::SDK_VERSION;
415
        }
416
    }
417
418
    /**
419
     * 根据管理接口uri拼接成完整的URL
420
     */
421
    protected function getManageUrl($uri)
422
    {
423
        return Conf::MANAGE_HOST_MEDIA . $uri;
424
    }
425
    protected function getNamespaceKey()
426
    {
427
        if ($this->type == "TOP") {
428
            return "namespace";
429
        } else {
430
            return "bucketName";
431
        }
432
    }
433
434
    /**
435
     * 获取管理鉴权信息
436
     */
437
    protected function getAuthorization($uri, $date, $httpBody)
438
    {
439
        $stringBeforeSign = "{$uri}\n{$httpBody}\n{$date}"; //1.生成待加签的原始字符串
440
        $signStr = hash_hmac('sha1', $stringBeforeSign, $this->sk); //2.使用SK对字符串计算HMAC-SHA1签名
441
        $preenCode = $this->ak . ":" . $signStr; //3.将签名与AK进行拼接
442
        $encodedStr = EncodeUtils::encodeWithURLSafeBase64($preenCode); //4.对拼接后的结果进行URL安全的Base64编码
443
        $manageToken = "ACL_" . $this->type . " " . $encodedStr; //5.最后为编码结果加上得到管理凭证
444
        return $manageToken;
445
    }
446
447
    /**
448
     * 得到当前时间的毫秒数
449
     */
450
    protected function currentMilliSecond()
451
    {
452
        list($microSec, $stampSec) = explode(' ', microtime());
453
        $tempMilli =  sprintf('%03s', intval($microSec * 1000));
454
        $currentMilli = $stampSec . $tempMilli;
455
        return $currentMilli;
456
    }
457
458
    /**
459
     * 反馈错误信息
460
     */
461
    protected function errorResponse($code = "UnknownError", $message = "unkonown error", $requestId = null)
462
    {
463
        return array(
464
            "isSuccess" => false,
465
            "code" => $code,
466
            "message" => $message,
467
            "requestId" => $requestId
468
        );
469
    }
470
}
471