Sfoglia il codice sorgente

增加华为云上传扩展类

liaofei 2 anni fa
parent
commit
e0179d64f5

+ 419 - 0
crmeb/crmeb/services/upload/extend/obs/Client.php

@@ -0,0 +1,419 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\upload\extend\obs;
+
+
+use crmeb\services\upload\extend\cos\XML;
+
+class Client
+{
+    const HEADER_PREFIX = 'x-obs-';
+
+    const INTEREST_HEADER_KEY_LIST = ['content-type', 'content-md5', 'date'];
+
+    const ALTERNATIVE_DATE_HEADER = 'x-obs-date';
+
+    const ALLOWED_RESOURCE_PARAMTER_NAMES = [
+        'acl',
+        'policy',
+        'torrent',
+        'logging',
+        'location',
+        'storageinfo',
+        'quota',
+        'storagepolicy',
+        'requestpayment',
+        'versions',
+        'versioning',
+        'versionid',
+        'uploads',
+        'uploadid',
+        'partnumber',
+        'website',
+        'notification',
+        'lifecycle',
+        'deletebucket',
+        'delete',
+        'cors',
+        'restore',
+        'tagging',
+        'response-content-type',
+        'response-content-language',
+        'response-expires',
+        'response-cache-control',
+        'response-content-disposition',
+        'response-content-encoding',
+        'x-image-process',
+
+        'backtosource',
+        'storageclass',
+        'replication',
+        'append',
+        'position',
+        'x-oss-process'
+    ];
+
+    const OBS_ACL = [
+        [
+            'value' => 'public-read',
+            'label' => '公共读(推荐)',
+        ],
+        [
+            'value' => 'public-read-write',
+            'label' => '公共读写',
+        ],
+    ];
+
+    const DEFAULT_OBS_ACL = 'public-read';
+
+    protected $isCname = false;
+
+    protected $pathStyle;
+
+    /**
+     * @var
+     */
+    protected $accessKeyId = 'AUL8K0BMYLSZTJDT9FCM';
+
+    /**
+     * @var
+     */
+    protected $secretKey = 'SwjS5huuunY6Bzjrhr7RGvOIA3kHkfNZuzIp8t2z';
+
+    /**
+     * 桶名
+     * @var string
+     */
+    protected $bucketName = '';
+
+    /**
+     * @var string
+     */
+    protected $baseUrl = 'obs.cn-north-1.myhuaweicloud.com';
+
+    public function __construct()
+    {
+
+    }
+
+    public function putObject()
+    {
+
+    }
+
+    /**
+     * 获取桶
+     * @return false|string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/5/16
+     */
+    public function getListBuckets()
+    {
+        return $this->request('https://' . $this->baseUrl . '/', 'GET', [], []);
+    }
+
+    public function createBucket(string $bucket, string $region, string $acl = self::DEFAULT_OBS_ACL)
+    {
+        $header = [
+            'x-obs-acl' => $acl,
+            'Host' => $this->getRequestUrl($bucket, $region),
+        ];
+
+        return $this->request('https://' . $header['Host'] . '/', 'PUT', [], $header);
+    }
+
+    protected function getRequestUrl(string $bucket, string $region)
+    {
+        return $bucket . '.obs.' . $region . '.myhuaweicloud.com';
+    }
+
+    /**
+     * 地域名称
+     * @return \string[][]
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/5/17
+     */
+    public function getRegion()
+    {
+        return [
+            [
+                'value' => 'cn-north-1',
+                'label' => '华北-北京一',
+            ],
+            [
+                'value' => 'cn-north-4',
+                'label' => '华北-北京四',
+            ],
+            [
+                'value' => 'cn-north-9',
+                'label' => '华北-乌兰察布一',
+            ],
+            [
+                'value' => 'cn-east-2',
+                'label' => '华东-上海二',
+            ],
+            [
+                'value' => 'cn-east-3',
+                'label' => '华东-上海一',
+            ],
+            [
+                'value' => 'cn-south-1',
+                'label' => '华南-广州',
+            ],
+            [
+                'value' => 'ap-southeast-1',
+                'label' => '中国-香港',
+            ],
+            [
+                'value' => 'cn-south-4',
+                'label' => '华南-广州-友好用户环境',
+            ],
+            [
+                'value' => 'cn-southwest-2',
+                'label' => '西南-贵阳一',
+            ],
+            [
+                'value' => 'la-north-2',
+                'label' => '拉美-墨西哥城二',
+            ],
+            [
+                'value' => 'na-mexico-1',
+                'label' => '拉美-墨西哥城一',
+            ],
+            [
+                'value' => 'sa-brazil-1',
+                'label' => '拉美-圣保罗一',
+            ],
+            [
+                'value' => 'la-south-2',
+                'label' => '拉美-圣地亚哥',
+            ],
+            [
+                'value' => 'tr-west-1',
+                'label' => '土耳其-伊斯坦布尔',
+            ],
+            [
+                'value' => 'ap-southeast-2',
+                'label' => '亚太-曼谷',
+            ],
+            [
+                'value' => 'ap-southeast-3',
+                'label' => '亚太-新加坡',
+            ],
+            [
+                'value' => 'af-south-1',
+                'label' => '非洲-约翰内斯堡',
+            ]
+        ];
+    }
+
+    /**
+     * 设置桶名
+     * @param string $bucketName
+     * @return $this
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/5/16
+     */
+    public function setBucketName(string $bucketName)
+    {
+        $this->bucketName = $bucketName;
+        return $this;
+    }
+
+
+    /**
+     * 获取签名
+     * @param array $result
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/5/17
+     */
+    protected function getSign(array $result)
+    {
+        $result['headers']['Date'] = gmdate('D, d M Y H:i:s \G\M\T');
+        $canonicalstring = $this->makeCanonicalstring($result['method'], $result['headers'], $result['pathArgs'], $result['dnsParam'], $result['uriParam']);
+
+        $result['cannonicalRequest'] = $canonicalstring;
+
+        $signature = base64_encode(hash_hmac('sha1', $canonicalstring, $this->secretKey, true));
+
+        $authorization = 'OBS ' . $this->accessKeyId . ':' . $signature;
+
+        $result['headers']['Authorization'] = $authorization;
+
+        return $result;
+    }
+
+    /**
+     * 处理签名数据
+     * @param $method
+     * @param $headers
+     * @param $pathArgs
+     * @param $bucketName
+     * @param $objectKey
+     * @param null $expires
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/5/17
+     */
+    public function makeCanonicalstring($method, $headers, $pathArgs, $bucketName, $objectKey, $expires = null)
+    {
+        $buffer = [];
+        $buffer[] = $method;
+        $buffer[] = "\n";
+        $interestHeaders = [];
+
+        foreach ($headers as $key => $value) {
+            $key = strtolower($key);
+            if (in_array($key, self::INTEREST_HEADER_KEY_LIST) || strpos($key, self::HEADER_PREFIX) === 0) {
+                $interestHeaders[$key] = $value;
+            }
+        }
+
+        if (array_key_exists(self::ALTERNATIVE_DATE_HEADER, $interestHeaders)) {
+            $interestHeaders['date'] = '';
+        }
+
+        if ($expires !== null) {
+            $interestHeaders['date'] = strval($expires);
+        }
+
+        if (!array_key_exists('content-type', $interestHeaders)) {
+            $interestHeaders['content-type'] = '';
+        }
+
+        if (!array_key_exists('content-md5', $interestHeaders)) {
+            $interestHeaders['content-md5'] = '';
+        }
+
+        ksort($interestHeaders);
+
+        foreach ($interestHeaders as $key => $value) {
+            if (strpos($key, self::HEADER_PREFIX) === 0) {
+                $buffer[] = $key . ':' . $value;
+            } else {
+                $buffer[] = $value;
+            }
+            $buffer[] = "\n";
+        }
+
+        $uri = '';
+
+        $bucketName = $this->isCname ? $headers['Host'] : $bucketName;
+
+        if ($bucketName) {
+            $uri .= '/';
+            $uri .= $bucketName;
+            if (!$this->pathStyle) {
+                $uri .= '/';
+            }
+        }
+
+        if ($objectKey) {
+            if (!($pos = strripos($uri, '/')) || strlen($uri) - 1 !== $pos) {
+                $uri .= '/';
+            }
+            $uri .= $objectKey;
+        }
+
+        $buffer[] = $uri === '' ? '/' : $uri;
+
+
+        if (!empty($pathArgs)) {
+            ksort($pathArgs);
+            $_pathArgs = [];
+            foreach ($pathArgs as $key => $value) {
+                if (in_array(strtolower($key), self::ALLOWED_RESOURCE_PARAMTER_NAMES) || strpos($key, self::HEADER_PREFIX) === 0) {
+                    $_pathArgs[] = $value === null || $value === '' ? $key : $key . '=' . urldecode($value);
+                }
+            }
+            if (!empty($_pathArgs)) {
+                $buffer[] = '?';
+                $buffer[] = implode('&', $_pathArgs);
+            }
+        }
+
+        return implode('', $buffer);
+    }
+
+    /**
+     * 发起请求
+     * @param string $url
+     * @param string $method
+     * @param array $data
+     * @param array $clientHeader
+     * @param int $timeout
+     * @return false|string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/5/16
+     */
+    public function request(string $url, string $method, array $data = [], array $clientHeader = [], int $timeout = 10)
+    {
+        $method = strtoupper($method);
+
+        $result = $this->getSign([
+            'method' => $method,
+            'headers' => $clientHeader,
+            'pathArgs' => '',
+            'dnsParam' => '',
+            'uriParam' => '',
+        ]);
+        $clientHeader = $result['headers'];
+        $headers = [];
+        foreach ($clientHeader as $key => $item) {
+            $headers[] = $key . ':' . $item;
+        }
+        $curl = curl_init($url);
+        //请求方式
+        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
+        //post请求
+        if (!empty($data['body'])) {
+            curl_setopt($curl, CURLOPT_POSTFIELDS, $data['body']);
+        } else if (!empty($data['json'])) {
+            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data['json']));
+        }
+        //超时时间
+        curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
+        //设置header头
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+
+        curl_setopt($curl, CURLOPT_FAILONERROR, false);
+        //返回抓取数据
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        //输出header头信息
+        curl_setopt($curl, CURLOPT_HEADER, true);
+        //TRUE 时追踪句柄的请求字符串,从 PHP 5.1.3 开始可用。这个很关键,就是允许你查看请求header
+        curl_setopt($curl, CURLINFO_HEADER_OUT, true);
+        //https请求
+        if (1 == strpos("$" . $url, "https://")) {
+            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+        }
+        [$content, $status] = [curl_exec($curl), curl_getinfo($curl)];
+//        dump($status);
+        $content = trim(substr($content, $status['header_size']));
+        $res = XML::parse($content);
+        if ($res) {
+            return $res;
+        }
+        return (intval($status["http_code"]) === 200) ? $content : false;
+    }
+
+}

+ 8 - 1
crmeb/crmeb/services/upload/storage/Cos.php

@@ -68,6 +68,11 @@ class Cos extends BaseUpload
      */
     protected $storageRegion;
 
+    /**
+     * @var string
+     */
+    protected $cdn;
+
     /**
      * 水印位置
      * @var string[]
@@ -98,6 +103,7 @@ class Cos extends BaseUpload
         $this->uploadUrl = $this->checkUploadUrl($config['uploadUrl'] ?? '');
         $this->storageName = $config['storageName'] ?? null;
         $this->storageRegion = $config['storageRegion'] ?? null;
+        $this->cdn = $config['cdn'] ?? null;
         $this->waterConfig['watermark_text_font'] = 'simfang仿宋.ttf';
     }
 
@@ -153,7 +159,7 @@ class Cos extends BaseUpload
         try {
             $key = $this->getUploadPath($key);
             $this->fileInfo->uploadInfo = $this->app()->putObject($key, $body);
-            $this->fileInfo->filePath = $this->uploadUrl . '/' . $key;
+            $this->fileInfo->filePath = ($this->cdn ?: $this->uploadUrl) . '/' . $key;
             $this->fileInfo->realName = isset($fileHandle) ? $fileHandle->getOriginalName() : $key;
             $this->fileInfo->fileName = $key;
             $this->fileInfo->filePathWater = $this->water($this->fileInfo->filePath);
@@ -304,6 +310,7 @@ class Cos extends BaseUpload
         // 获取临时密钥,计算签名
         $result = $sts->getTempKeys($config);
         $result['url'] = $this->uploadUrl . '/';
+        $result['cdn'] = $this->cdn;
         $result['type'] = 'COS';
         $result['bucket'] = $this->storageName;
         $result['region'] = $this->storageRegion;

+ 9 - 2
crmeb/crmeb/services/upload/storage/Oss.php

@@ -78,6 +78,11 @@ class Oss extends BaseUpload
         '9' => 'se',//:右下
     ];
 
+    /**
+     * @var string
+     */
+    protected $cdn;
+
     /**
      * 初始化
      * @param array $config
@@ -90,6 +95,7 @@ class Oss extends BaseUpload
         $this->secretKey = $config['secretKey'] ?? null;
         $this->uploadUrl = $this->checkUploadUrl($config['uploadUrl'] ?? '');
         $this->storageName = $config['storageName'] ?? null;
+        $this->cdn = $config['cdn'] ?? null;
         $this->storageRegion = $config['storageRegion'] ?? null;
     }
 
@@ -143,7 +149,7 @@ class Oss extends BaseUpload
             }
             $this->fileInfo->uploadInfo = $uploadInfo;
             $this->fileInfo->realName = $fileHandle->getOriginalName();
-            $this->fileInfo->filePath = $this->uploadUrl . '/' . $key;
+            $this->fileInfo->filePath = ($this->cdn ?: $this->uploadUrl) . '/' . $key;
             $this->fileInfo->fileName = $key;
             $this->fileInfo->filePathWater = $this->water($this->fileInfo->filePath);
             $this->authThumb && $this->thumb($this->fileInfo->filePath);
@@ -174,7 +180,7 @@ class Oss extends BaseUpload
             }
             $this->fileInfo->uploadInfo = $uploadInfo;
             $this->fileInfo->realName = $key;
-            $this->fileInfo->filePath = $this->uploadUrl . '/' . $key;
+            $this->fileInfo->filePath = ($this->cdn ?: $this->uploadUrl) . '/' . $key;
             $this->fileInfo->fileName = $key;
             $this->fileInfo->filePathWater = $this->water($this->fileInfo->filePath);
             $this->thumb($this->fileInfo->filePath);
@@ -290,6 +296,7 @@ class Oss extends BaseUpload
         return [
             'accessid' => $this->accessKey,
             'host' => $this->uploadUrl,
+            'cdn' => $this->cdn,
             'policy' => $base64Policy,
             'signature' => $signature,
             'expire' => time() + 30,

+ 9 - 2
crmeb/crmeb/services/upload/storage/Qiniu.php

@@ -79,6 +79,11 @@ class Qiniu extends BaseUpload
         '9' => 'SouthEast',//:右下
     ];
 
+    /**
+     * @var string
+     */
+    protected $cdn;
+
     /**
      * 初始化
      * @param array $config
@@ -91,6 +96,7 @@ class Qiniu extends BaseUpload
         $this->secretKey = $config['secretKey'] ?? null;
         $this->uploadUrl = $this->checkUploadUrl($config['uploadUrl'] ?? '');
         $this->storageName = $config['storageName'] ?? null;
+        $this->cdn = $config['cdn'] ?? null;
         $this->storageRegion = $config['storageRegion'] ?? null;
     }
 
@@ -172,7 +178,7 @@ class Qiniu extends BaseUpload
             }
             $this->fileInfo->uploadInfo = $result;
             $this->fileInfo->realName = $key;
-            $this->fileInfo->filePath = $this->uploadUrl . '/' . $key;
+            $this->fileInfo->filePath = ($this->cdn ?: $this->uploadUrl) . '/' . $key;
             $this->fileInfo->fileName = $key;
             $this->fileInfo->filePathWater = $this->water($this->fileInfo->filePath);
             $this->thumb($this->fileInfo->filePath);
@@ -281,9 +287,10 @@ class Qiniu extends BaseUpload
     {
         $token = $this->app()->uploadToken($this->storageName);
         $domain = $this->uploadUrl;
+        $cdn = $this->cdn;
         $key = $this->saveFileName(NULL, 'mp4');
         $type = 'QINIU';
-        return compact('token', 'domain', 'key', 'type');
+        return compact('token', 'domain', 'key', 'type', 'cdn');
     }
 
     /**