初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

3
vendor/liz/flysystem-qiniu/.gitignore vendored Executable file
View File

@@ -0,0 +1,3 @@
/vendor
/.idea/
/index.php

1
vendor/liz/flysystem-qiniu/.php_cs.cache vendored Executable file
View File

@@ -0,0 +1 @@
{"php":"7.3.5","version":"2.15.3:v2.15.3#705490b0f282f21017d73561e9498d2b622ee34c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":true,"blank_line_after_opening_tag":true,"braces":{"allow_single_line_closure":true},"cast_spaces":true,"class_attributes_separation":{"elements":["method"]},"class_definition":{"single_line":true},"concat_space":true,"declare_equal_normalize":true,"function_typehint_space":true,"include":true,"increment_style":true,"lowercase_cast":true,"lowercase_static_reference":true,"magic_constant_casing":true,"magic_method_casing":true,"method_argument_space":true,"native_function_casing":true,"native_function_type_declaration_casing":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_blank_lines":{"tokens":["curly_brace_block","extra","parenthesis_brace_block","square_brace_block","throw","use"]},"no_leading_import_slash":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":true,"no_multiline_whitespace_around_double_arrow":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_trailing_comma_in_list_call":true,"no_trailing_comma_in_singleline_array":true,"no_unneeded_control_parentheses":true,"no_unneeded_curly_braces":true,"no_unneeded_final_method":true,"no_unused_imports":true,"no_whitespace_before_comma_in_array":true,"no_whitespace_in_blank_line":true,"normalize_index_brace":true,"object_operator_without_whitespace":true,"php_unit_fqcn_annotation":true,"phpdoc_align":{"tags":["method","param","property","return","throws","type","var"]},"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":true,"phpdoc_no_empty_return":true,"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_return_self_reference":true,"phpdoc_scalar":true,"phpdoc_separation":true,"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_to_comment":true,"phpdoc_trim":true,"phpdoc_types":true,"phpdoc_types_order":{"null_adjustment":"always_last","sort_algorithm":"none"},"phpdoc_var_without_name":true,"protected_to_private":true,"return_type_declaration":true,"semicolon_after_instruction":true,"short_scalar_cast":true,"single_blank_line_before_namespace":true,"single_class_element_per_statement":true,"single_line_comment_style":{"comment_types":["hash"]},"single_quote":true,"single_trait_insert_per_statement":true,"space_after_semicolon":{"remove_in_empty_for_expressions":true},"standardize_increment":true,"standardize_not_equals":true,"ternary_operator_spaces":true,"trailing_comma_in_multiline_array":true,"trim_array_spaces":true,"unary_operator_spaces":true,"whitespace_after_comma_in_array":true,"yoda_style":true,"blank_line_after_namespace":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_constants":true,"lowercase_keywords":true,"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"strict_comparison":true},"hashes":{"src\\Plugins\\PrivateDownloadUrlMaker.php":973172363,"src\\Plugins\\TransCoder.php":2163609133,"src\\QiNiuOssAdapter.php":1538278121,"src\\QiNiuOssAdapterException.php":3087784321}}

134
vendor/liz/flysystem-qiniu/README.md vendored Executable file
View File

@@ -0,0 +1,134 @@
## QiNiu OSS(七牛云对象存储) Adapter For Flysystem.
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
Flysystem 适配器: [七牛云](https://www.qiniu.com/)
## Installation
composer require liz/flysystem-qiniu
## Usage
```php
require 'vendor/autoload.php';
use League\Flysystem\Filesystem;
use Liz\Flysystem\QiNiu\Plugins\PrivateDownloadUrlMaker;
use Liz\Flysystem\QiNiu\Plugins\TransCoder;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
use Liz\Flysystem\QiNiu\QiNiuOssAdapterException;
# cdn [外链默认域名须英文](https://developer.qiniu.com/kodo/kb/5158/how-to-transition-from-test-domain-name-to-a-custom-domain-name)
$cdnHost = 'cdn.host.com';
# bucket [七牛对象存储空间列表](https://portal.qiniu.com/bucket)
$bucket = 'bucket';
# $accessKey [用户密钥](https://portal.qiniu.com/user/key)
$accessKey = 'access-key';
$secretKey = 'secret-key';
$flysystem = new Filesystem(new QiNiuOssAdapter($accessKey, $secretKey, $bucket, $cdnHost));
try {
// 创建文件夹
$result = $flysystem->createDir('path/dir');
var_dump($result);
// 删除文件夹
$result = $flysystem->deleteDir('path/dir');
var_dump($result);
// has file
$isExist = $flysystem->has('path/file.txt');
// write file
if (!$isExist){
$result = $flysystem->write('path/file.txt', 'contents');
var_dump($result);
}
// write stream
if (!$flysystem->has('path/filename.txt')){
$stream = fopen('.gitignore', 'r+');
$result = $flysystem->writeStream('path/file name.txt', $stream);
var_dump($result);
$result = $flysystem->read('path/file name.txt');
var_dump($result);
}
// update file
$result = $flysystem->update('path/file.txt', 'new contents');
var_dump($result);
// read file
$result = $flysystem->read('path/file.txt');
var_dump($result);
// rename files
if(!$flysystem->has('path/newname.txt')){
$result = $flysystem->rename('path/file name.txt', 'path/newname.txt');
var_dump($result);
}
// copy files
if (!$flysystem->has('path/file_copy.txt')){
$result = $flysystem->copy('path/file.txt', 'path/file_copy.txt');
}
// list the contents
$result = $flysystem->listContents('path', false);
var_dump($result);
// delete file
$result = $flysystem->delete('path/file.txt');
var_dump($result);
// 转码
/**
* @var $flysystem Filesystem|QiNiuOssAdapter
*/
$flysystem = new Filesystem(new QiNiuOssAdapter($accessKey, $secretKey, $bucket, $cdnHost));
/**
* TransCoder constructor.
* @param null $notifyUrl 处理完毕默认通知地址
* @param null $pipeLine 默认队列名称 https://portal.qiniu.com/dora/mps/new
* @param null $toBucket 处理完成默认保存到的bucket
* @param null $wmImage 水印图片地址
*/
$flysystem->addPlugin(new TransCoder('notify_url', 'pipeline', 'toBucket', 'wmImage')); //设置转码默认选项
// 转码样式说明 https://developer.qiniu.com/kodo/kb/5858/the-instructions-on-the-storage-space-of-transcoding-style
$rules = 'm3u8/segtime/10/ab/128k/ar/44100/acodec/libfaac/r/30/vb/640k/vcodec/libx264/stripmeta/0/noDomain/1';
/**
* @param $path 待转码文件路径
* @param $rules 转码规则[转码规则说明](https://developer.qiniu.com/kodo/kb/5858/the-instructions-on-the-storage-space-of-transcoding-style)
* @param null $pipeline 队列名称,若不填写使用TransCoder初始化的pipeline https://portal.qiniu.com/dora/mps/new
* @param null $notifyUrl 处理完毕通知地址,若不填写使用TransCoder初始化的bucket
* @param null $saveAs 保存全部路径,若不填写则为$path的名称加_trans
* @param null $bucket 处理完成保存到bucket若不填写则使用TransCoder初始化的bucket
*
* @return array
*
* @throws QiNiuOssAdapterException
*/
$result = $flysystem->transCoding('xxw-community/a.mp4', $rules, 'xxw-community/a.m3u8', 'notify_url', 'first', 'to_bucket');
var_dump($result);
//获取私有下载地址
$flysystem->addPlugin(new PrivateDownloadUrlMaker());
/**
* @param string $baseUrl 请求url
* @param bool $isBucketPrivate bucket是否为私有如果是私有m3u8文件会对相关ts文件进行授权处理(https://developer.qiniu.com/dora/api/1292/private-m3u8-pm3u8)
* @param int $expires
* @return string
*/
$url = $flysystem->privateDownloadUrl('xxw-community/a.m3u8', true);
var_dump($url);
//获取上传token
$flysystem->addPlugin(new UploadTokenMaker());
$token = $flysystem->getUploadToken('upload/token/file.txt');
var_dump($token);
}catch (Exception $exception){
echo "<pre>";
var_dump($exception);
}
```
## Notice
`getVisibility()`,`setVisibility()`七牛云没有提供相关操作只能对整个bucket进行私有或公共访问的操作

22
vendor/liz/flysystem-qiniu/composer.json vendored Executable file
View File

@@ -0,0 +1,22 @@
{
"name": "liz/flysystem-qiniu",
"description": "QiNiu oss adapter for flysystem",
"type": "library",
"require": {
"league/flysystem": "^1.0",
"qiniu/php-sdk": "^7.2",
"php": "^7.0 || ^8.0"
},
"license": "MIT",
"authors": [
{
"name": "liz in company",
"email": "396635210@qq.com"
}
],
"autoload": {
"psr-4": {
"Liz\\Flysystem\\QiNiu\\": "src"
}
}
}

155
vendor/liz/flysystem-qiniu/composer.lock generated vendored Executable file
View File

@@ -0,0 +1,155 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "297862205eb464da0b37b85e726662c9",
"packages": [
{
"name": "league/flysystem",
"version": "1.0.55",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "33c91155537c6dc899eacdc54a13ac6303f156e6"
},
"dist": {
"type": "zip",
"url": "https://github-api-proxy.cnpkg.org/repos/thephpleague/flysystem/zipball/33c91155537c6dc899eacdc54a13ac6303f156e6",
"reference": "33c91155537c6dc899eacdc54a13ac6303f156e6",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"php": ">=5.5.9"
},
"conflict": {
"league/flysystem-sftp": "<1.0.6"
},
"require-dev": {
"phpspec/phpspec": "^3.4",
"phpunit/phpunit": "^5.7.10"
},
"suggest": {
"ext-fileinfo": "Required for MimeType",
"ext-ftp": "Allows you to use FTP server storage",
"ext-openssl": "Allows you to use FTPS server storage",
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src/"
}
},
"notification-url": "https://repo.packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frenky.net"
}
],
"description": "Filesystem abstraction: Many filesystems, one API.",
"keywords": [
"Cloud Files",
"WebDAV",
"abstraction",
"aws",
"cloud",
"copy.com",
"dropbox",
"file systems",
"files",
"filesystem",
"filesystems",
"ftp",
"rackspace",
"remote",
"s3",
"sftp",
"storage"
],
"time": "2019-08-24T11:17:19+00:00"
},
{
"name": "qiniu/php-sdk",
"version": "v7.2.9",
"source": {
"type": "git",
"url": "https://github.com/qiniu/php-sdk.git",
"reference": "afe7d8715d8a688b1d8d8cdf031240d2363dad90"
},
"dist": {
"type": "zip",
"url": "https://github-api-proxy.cnpkg.org/repos/qiniu/php-sdk/zipball/afe7d8715d8a688b1d8d8cdf031240d2363dad90",
"reference": "afe7d8715d8a688b1d8d8cdf031240d2363dad90",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~2.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Qiniu\\": "src/Qiniu"
},
"files": [
"src/Qiniu/functions.php"
]
},
"notification-url": "https://repo.packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Qiniu",
"email": "sdk@qiniu.com",
"homepage": "http://www.qiniu.com"
}
],
"description": "Qiniu Resource (Cloud) Storage SDK for PHP",
"homepage": "http://developer.qiniu.com/",
"keywords": [
"cloud",
"qiniu",
"sdk",
"storage"
],
"time": "2019-07-09T07:55:07+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^7.0"
},
"platform-dev": []
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins;
use League\Flysystem\Plugin\AbstractPlugin;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
class AuthGetter extends AbstractPlugin
{
public function getMethod()
{
return 'getAuth';
}
/**
* @return QiNiuOssAdapter
*/
protected function getFlySystemAdapter()
{
return $this->filesystem->getAdapter();
}
/**
* @return \Qiniu\Processing\PersistentFop
*/
public function handle()
{
return $this->getFlySystemAdapter()->getFopManager();
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins;
use League\Flysystem\Plugin\AbstractPlugin;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
use Qiniu\Auth;
class FopManagerGetter extends AbstractPlugin
{
public function getMethod()
{
return 'getAuth';
}
/**
* @return QiNiuOssAdapter
*/
protected function getFlySystemAdapter()
{
return $this->filesystem->getAdapter();
}
/**
* @return Auth
*/
public function handle()
{
return $this->getFlySystemAdapter()->getAuth();
}
}

View File

@@ -0,0 +1,45 @@
<?php
/**
* Created by PhpStorm.
* User: dljy-technology
* Date: 2018/12/27
* Time: 上午11:31.
*/
namespace Liz\Flysystem\QiNiu\Plugins;
use League\Flysystem\Plugin\AbstractPlugin;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
/**
* Class PrivateDownloadUrlMaker.
*
* @method string privateDownloadUrl(获取私有文件的地址 $baseUrl, bucket是否私有 $isBucketPrivate = false, 访问超时时间 $expires = 3600)
*/
class PrivateDownloadUrlMaker extends AbstractPlugin
{
public function getMethod()
{
return 'privateDownloadUrl';
}
/**
* @return QiNiuOssAdapter
*/
protected function getFlySystemAdapter()
{
return $this->filesystem->getAdapter();
}
/**
* @param $baseUrl
* @param bool $isBucketPrivate
* @param int $expires
*
* @return string
*/
public function handle($baseUrl, $isBucketPrivate = false, $expires = 3600)
{
return $this->getFlySystemAdapter()->privateDownloadUrl($baseUrl, $isBucketPrivate, $expires);
}
}

View File

@@ -0,0 +1,96 @@
<?php
/**
* Created by PhpStorm.
* User: dljy-technology
* Date: 2018/12/27
* Time: 上午11:31.
*/
namespace Liz\Flysystem\QiNiu\Plugins;
use League\Flysystem\Plugin\AbstractPlugin;
use Liz\Flysystem\QiNiu\Plugins\TransCoderHelpers\AbstractTransCoderPolicy;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
use function Qiniu\base64_urlSafeEncode;
/**
* Class TransCoder.
*
* @method array transCoding(需要进行转码的文件全路径 $path, 转码规则 $rules, 另存文件全路径 $saveAs=null, 通知地址 $notifyUrl=null, 队列名称 $pipeline=null, 保存bucket $bucket=null)
*/
class TransCoder extends AbstractPlugin
{
protected $notifyUrl;
protected $pipeLine;
protected $toBucket;
protected $wmImage;
/**
* @var null
*/
private $rules;
/**
* TransCoder constructor.
*
* @param null $notifyUrl 处理完毕默认通知地址
* @param null $pipeLine 默认队列名称 https://portal.qiniu.com/dora/mps/new
* @param null $toBucket 处理完成默认保存到的bucket
* @param null $wmImage 水印图片地址
*/
public function __construct($notifyUrl = null, $pipeLine = null, $toBucket = null, $wmImage = null, $rules = null)
{
$this->notifyUrl = $notifyUrl;
$this->pipeLine = $pipeLine;
$this->toBucket = $toBucket;
$this->wmImage = $wmImage;
$this->rules = $rules;
}
public function setPolicy(AbstractTransCoderPolicy $transCoderPolicy){
$this->notifyUrl = $transCoderPolicy->getNotifyUrl();
$this->pipeLine = $transCoderPolicy->getPipeLine();
$this->toBucket = $transCoderPolicy->getToBucket();
$this->wmImage = $transCoderPolicy->getWmImage();
$this->rules = $transCoderPolicy->getRules();
}
public function getMethod()
{
return 'transCoding';
}
/**
* @return QiNiuOssAdapter
*/
protected function getFlySystemAdapter()
{
return $this->filesystem->getAdapter();
}
/**
* @param $path
* @param $rules
* @param null $saveAs
* @param null $notifyUrl
* @param null $pipeline
* @param null $toBucket
*
* @return array
*
* @throws \Liz\Flysystem\QiNiu\QiNiuOssAdapterException
*/
public function handle($path, $rules, $saveAs = null, $notifyUrl = null, $pipeline = null, $toBucket = null)
{
$notifyUrl = $notifyUrl ?: $this->notifyUrl;
$pipeline = $pipeline ?: $this->pipeLine;
$toBucket = $toBucket ?: $this->toBucket;
$rules = $rules ?: $this->rules;
if ($this->wmImage && !strstr($rules, 'wmImage')) {
$rules .= '/wmImage/'.base64_urlSafeEncode($this->wmImage);
}
return $this->getFlySystemAdapter()->transCoding($path, $rules, $saveAs, $notifyUrl, $pipeline, $toBucket);
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins\TransCoderHelpers;
abstract class AbstractTransCoderPolicy
{
/**
* @return string
*/
abstract public function getNotifyUrl();
/**
* @param string $notifyUrl
*/
abstract public function setNotifyUrl(string $notifyUrl);
/**
* @return string
*/
abstract public function getPipeLine();
/**
* @param string $pipeLine
*/
abstract public function setPipeLine(string $pipeLine);
/**
* @return string
*/
abstract public function getToBucket();
/**
* @param string $toBucket
*/
abstract public function setToBucket(string $toBucket);
/**
* @return string
*/
abstract public function getWmImage();
/**
* @param mixed $wmImage
*/
abstract public function setWmImage(string $wmImage);
/**
* @param string $rules
*/
abstract public function setRules(string $rules);
/**
* @return string
*/
abstract public function getRules();
/**
* @param string $rules
*/
abstract public function setUploadPersistentOps(string $rules);
/**
* @return string
*/
abstract public function getUploadPersistentOps();
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins;
use League\Flysystem\Plugin\AbstractPlugin;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
class UploadCallbackValidator extends AbstractPlugin
{
public function getMethod()
{
return 'verifyUploadCallback';
}
/**
* @return QiNiuOssAdapter
*/
protected function getFlySystemAdapter()
{
return $this->filesystem->getAdapter();
}
/**
* @param $contentType
* @param $authorization
* @param $url
* @param $callbackBody
* @return bool
*/
public function handle($contentType, $authorization, $url, $callbackBody)
{
return $this->getFlySystemAdapter()->verifyUploadCallback($contentType, $authorization, $url, $callbackBody);
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* Created by PhpStorm.
* User: dljy-technology
* Date: 2018/12/27
* Time: 上午11:31.
*/
namespace Liz\Flysystem\QiNiu\Plugins;
use League\Flysystem\Plugin\AbstractPlugin;
use Liz\Flysystem\QiNiu\Plugins\TransCoderHelpers\AbstractTransCoderPolicy;
use Liz\Flysystem\QiNiu\Plugins\UploadTokenMakerHelpers\AbstractUploadPolicy;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
/**
* Class PrivateDownloadUrlMaker.
*
* @method string getUploadToken($pathname, $expires = 3600, array $policy = [])
*/
class UploadTokenMaker extends AbstractPlugin
{
/**
* @var AbstractUploadPolicy
*/
private $uploadPolicy;
public function setDefaultPolicy(AbstractUploadPolicy $uploadPolicy){
$this->uploadPolicy = $uploadPolicy;
}
public function getMethod()
{
return 'getUploadToken';
}
/**
* @return QiNiuOssAdapter
*/
protected function getFlySystemAdapter()
{
return $this->filesystem->getAdapter();
}
/**
* @param $pathname
* @param int $expires
* @param array $policy
* @return string
*/
public function handle($pathname, $expires = 3600, array $policy = [])
{
$policy = $this->generatePolicy($policy);
return $this->getFlySystemAdapter()->getUploadToken($pathname, $expires, $policy);
}
private function generatePolicy(array $policy)
{
if (!$this->uploadPolicy){
return $policy;
}
if (!isset($policy['callbackUrl'])){
$urls = $this->uploadPolicy->getCallbackUrls();
$urlsString = implode(";", $urls);
$policy['callbackUrl'] = $urlsString;
}
if (!isset($policy['callbackBody'])){
$policy['callbackBody'] = $this->uploadPolicy->getCallbackBody();
}
if (!isset($policy['callbackBodyType'])){
$policy['callbackBodyType'] = $this->uploadPolicy->getCallbackBodyType();
}
if ($this->uploadPolicy->getTransCoderPolicy()){
$transCoderPolicy = $this->uploadPolicy->getTransCoderPolicy();
$policy['persistentOps'] = $transCoderPolicy->getUploadPersistentOps();
$policy['persistentNotifyUrl'] = $transCoderPolicy->getNotifyUrl();
$policy['persistentPipeline'] = $transCoderPolicy->getPipeLine();
}
return $policy;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins\UploadTokenMakerHelpers;
use Liz\Flysystem\QiNiu\Plugins\TransCoderHelpers\AbstractTransCoderPolicy;
abstract class AbstractUploadPolicy
{
const CallbackBodyTypeForm = 'application/x-www-form-urlencoded';
const CallbackBodyTypeJson = 'application/json';
protected static $callbackBodyTypes = [
'qiniu.upload_policy.callback_body_type.form' => self::CallbackBodyTypeForm,
'qiniu.upload_policy.callback_body_type.json' => self::CallbackBodyTypeJson,
];
abstract public function addCallbackUrl(string $callbackUrl);
abstract public function getCallbackUrls();
abstract public function setCallbackBody(string $callbackBody);
abstract public function getCallbackBody();
abstract public function setCallbackBodyType(string $bodyType);
abstract public function getCallbackBodyType();
abstract public function setTransCoderPolicy(AbstractTransCoderPolicy $transCoderPolicy=null);
/**
* @return AbstractTransCoderPolicy
*/
abstract public function getTransCoderPolicy();
/**
* @return array
*/
public static function getCallbackBodyTypes(): array
{
return self::$callbackBodyTypes;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins;
use League\Flysystem\Plugin\AbstractPlugin;
use Liz\Flysystem\QiNiu\Plugins\VFrameHelpers\AbstractVFramePolicy;
use Liz\Flysystem\QiNiu\QiNiuOssAdapter;
class VFrameCutter extends AbstractPlugin
{
public function getMethod()
{
return 'vframe';
}
public function handle($path, AbstractVFramePolicy $policy){
$this->getFlySystemAdapter()->vframe($path, $policy);
}
/**
* @return QiNiuOssAdapter
*/
protected function getFlySystemAdapter()
{
return $this->filesystem->getAdapter();
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins\VFrameHelpers;
abstract class AbstractVFramePolicy
{
const FormatJPG = 'jpg';
const FormatPNG = 'png';
const Rotate90 = '90';
const Rotate180 = '180';
const Rotate270 = '270';
const RotateAuto = 'auto';
protected static $formats = [
'qiniu.vframe.format_jpg' => self::FormatJPG,
'qiniu.vframe.format_png' => self::FormatPNG,
];
protected static $rotates = [
'qiniu.vframe.rotate.90' => self::Rotate90,
'qiniu.vframe.rotate.180' => self::Rotate180,
'qiniu.vframe.rotate.270' => self::Rotate270,
'qiniu.vframe.rotate.auto' => self::RotateAuto,
];
/**
* @return array
*/
public static function getFormats(): array
{
return self::$formats;
}
/**
* @return array
*/
public static function getRotates(): array
{
return self::$rotates;
}
/**
* @return string
*/
abstract public function getFormat();
/**
* @param string $format
*/
abstract public function setFormat(string $format);
/**
* @return int
*/
abstract public function getWidth();
/**
* @param int $width
*/
abstract public function setWidth(int $width);
/**
* @return int
*/
abstract public function getHeight();
/**
* @param int $height
*/
abstract public function setHeight(int $height);
/**
* @return int
*/
abstract public function getOffset();
/**
* @param int $offset
*/
abstract public function setOffset(int $offset);
/**
* @return string
*/
abstract public function getRotate();
/**
* @param string $rotate
*/
abstract public function setRotate(string $rotate);
/**
* @return string
*/
abstract public function getNotifyUrl();
/**
* @param string $notifyUrl
*/
abstract public function setNotifyUrl(string $notifyUrl);
/**
* @return string
*/
abstract public function getPipeLine();
/**
* @param string $pipeLine
*/
abstract public function setPipeLine(string $pipeLine);
}

View File

@@ -0,0 +1,137 @@
<?php
namespace Liz\Flysystem\QiNiu\Plugins\VFrameHelpers;
class QiNiuVFramePolicy extends AbstractVFramePolicy
{
protected $format;
protected $offset;
protected $width;
protected $height;
protected $rotate;
protected $pipeline;
protected $notifyUrl;
/**
* @return mixed
*/
public function getFormat()
{
return $this->format;
}
/**
* @param mixed $format
*/
public function setFormat(string $format)
{
$this->format = $format;
}
/**
* @return mixed
*/
public function getOffset()
{
return $this->offset;
}
/**
* @param mixed $offset
*/
public function setOffset(int $offset)
{
$this->offset = $offset;
}
/**
* @return mixed
*/
public function getWidth()
{
return $this->width;
}
/**
* @param mixed $width
*/
public function setWidth(int $width)
{
$this->width = $width;
}
/**
* @return mixed
*/
public function getHeight()
{
return $this->height;
}
/**
* @param mixed $height
*/
public function setHeight(int $height)
{
$this->height = $height;
}
/**
* @return mixed
*/
public function getRotate()
{
return $this->rotate;
}
/**
* @param mixed $rotate
*/
public function setRotate(string $rotate)
{
$this->rotate = $rotate;
}
/**
* @return mixed
*/
public function getPipeline()
{
return $this->pipeline;
}
/**
* @param mixed $pipeline
*/
public function setPipeline(string $pipeline)
{
$this->pipeline = $pipeline;
}
/**
* @return mixed
*/
public function getNotifyUrl()
{
return $this->notifyUrl;
}
/**
* @param mixed $notifyUrl
*/
public function setNotifyUrl(string $notifyUrl)
{
$this->notifyUrl = $notifyUrl;
}
}

View File

@@ -0,0 +1,572 @@
<?php
namespace Liz\Flysystem\QiNiu;
use League\Flysystem\Adapter\AbstractAdapter;
use League\Flysystem\Config;
use Liz\Flysystem\QiNiu\Plugins\VFrameHelpers\AbstractVFramePolicy;
use Qiniu\Auth;
use function Qiniu\base64_urlSafeEncode;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
use Qiniu\Processing\PersistentFop;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;
class QiNiuOssAdapter extends AbstractAdapter
{
private $client;
private $auth;
private $bucket;
private $host;
private $bucketManager;
private $uploadManager;
private $fopManager;
/**
* @return string
*/
protected function getBucket(): string
{
return $this->bucket;
}
/**
* QiNiuOssAdapter constructor.
*
* @param string $cdnHost
* @param string $bucket
* @param string $accessKey
* @param string $secretKey
*/
public function __construct($accessKey, $secretKey, $bucket, $cdnHost)
{
$this->makeHost($cdnHost);
$this->auth = new Auth($accessKey, $secretKey);
$this->bucket = $bucket;
$this->client = new Client();
}
public function getAuth(){
return $this->auth;
}
public function verifyUploadCallback($contentType, $authorization, $url, $callbackBody){
return $this->auth->verifyCallback($contentType, $authorization, $url, $callbackBody);
}
/**
* @param $pathname 保存路径 path/to/filename.ext
* @param int $expires token时限
* @param array $policy 上传策略,关联数组 https://developer.qiniu.com/kodo/manual/1206/put-policy
* @return string
*/
public function getUploadToken($pathname, $expires = 3600, array $policy = []){
if (!$policy){
$policy = null;
}
$uploadToken = $this->auth->uploadToken($this->bucket, $pathname, $expires, $policy, false);
return $uploadToken;
}
/**
* @param string $path
* @param string $contents
* @param Config $config
*
* @return array|false
*
* @throws QiNiuOssAdapterException
*/
public function write($path, $contents, Config $config)
{
$uploadToken = $this->auth->uploadToken($this->bucket);
$response = $this->getUploadManager()->put($uploadToken, $path, $contents);
$this->ossResponse($response);
return $this->mapFileInfo($path, true, ['contents' => $contents]);
}
/**
* @param string $path
* @param resource $resource
* @param Config $config
*
* @return array|false
*
* @throws QiNiuOssAdapterException
*/
public function writeStream($path, $resource, Config $config)
{
return $this->write($path, stream_get_contents($resource), $config);
}
/**
* @param string $path
* @param string $contents
* @param Config $config
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function update($path, $contents, Config $config)
{
$uploadToken = $this->auth->uploadToken($this->bucket, $path);
$response = $this->getUploadManager()->put($uploadToken, $path, $contents);
$this->ossResponse($response);
return $this->mapFileInfo($path);
}
/**
* @param string $path
* @param resource $resource
* @param Config $config
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function updateStream($path, $resource, Config $config)
{
return $this->update($path, stream_get_contents($resource), $config);
}
/**
* @param string $path
* @param string $newpath
*
* @return bool
*/
public function rename($path, $newpath)
{
$error = $this->getBucketManager()->rename($this->bucket, $path, $newpath);
$this->createExceptionIfError($error);
return !$error;
}
/**
* @param string $path
* @param string $newpath
*
* @return bool
*/
public function copy($path, $newpath)
{
$error = $this->getBucketManager()->copy($this->bucket, $path, $this->bucket, $newpath);
$this->createExceptionIfError($error);
return !$error;
}
/**
* @param string $path
*
* @return bool
*/
public function delete($path)
{
$response = $this->getBucketManager()->delete($this->bucket, $path);
return !$response;
}
/**
* @param string $dirname
*
* @return bool
*/
public function deleteDir($dirname)
{
return true;
}
/**
* @param string $dirname
* @param Config $config
*
* @return array|false
*
* @throws QiNiuOssAdapterException
*/
public function createDir($dirname, Config $config)
{
$this->write($dirname.'/.init', 'hello world', $config);
return $this->mapDirInfo($dirname);
}
/**
* @param string $path
* @param string $visibility
*
* @return array|false|void
*/
public function setVisibility($path, $visibility)
{
// TODO: Implement setVisibility() method. 七牛云没有此功能只能对整个bucket设置私有或公共
}
/**
* @param string $path
*
* @return array|bool|null
*/
public function has($path)
{
$response = $this->getBucketManager()->stat($this->bucket, $path);
return !$response[1];
}
/**
* @param string $path
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function read($path)
{
$response = $this->getBucketManager()->stat($this->bucket, $path);
$this->ossResponse($response);
$path = $this->urlEncode($path);
$privateUrl = $this->privateDownloadUrl($path);
$result = $this->mapFileInfo($path, false, [
'contents' => file_get_contents($privateUrl),
]);
return $result;
}
/**
* @param string $path
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function readStream($path)
{
$path = $this->urlEncode($path);
$url = $path;
if (!stripos($path, 'token')){
$url = $this->privateDownloadUrl($this->host.$path);
}
$stream = fopen($url, 'rb');
return $this->mapFileInfo($path, false, ['stream' => $stream]);
}
/**
* @param string $directory
* @param bool $recursive
*
* @return array
*
* @throws QiNiuOssAdapterException
*/
public function listContents($directory = '', $recursive = false)
{
$directory = $recursive ? '' : $directory;
$response = $this->getBucketManager()->listFiles($this->getBucket(), $directory);
$this->ossResponse($response);
$getDir = function ($path, $currentDir) {
$tmp = strtr($path, [
$currentDir.'/' => '',
]);
return substr($tmp, 0, stripos($tmp, '/'));
};
$files = $response['items'] ?: [];
$results = [];
foreach ($files as $file) {
$dir = $getDir($file['key'], $directory);
if ($dir) {
$result = $this->mapDirInfo($directory.'/'.$dir);
} else {
$result = $this->mapFileInfo($file['key'], false, [
'timestamp' => (int) ceil($file['putTime'] / 1000 / 10000),
'size' => $file['fsize'],
]);
}
$results[] = $result;
}
$results = array_unique($results, SORT_REGULAR);
return $results;
}
/**
* @param string $path
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function getMetadata($path)
{
return $this->mapFileInfo($path, true);
}
/**
* @param string $path
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function getSize($path)
{
return $this->getMetadata($path);
}
/**
* @param string $path
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function getMimetype($path)
{
return $this->getMetadata($path);
}
/**
* @param string $path
*
* @return array|false|mixed
*
* @throws QiNiuOssAdapterException
*/
public function getTimestamp($path)
{
return $this->getMetadata($path);
}
/**
* @param string $path
*
* @return array|false|void
*/
public function getVisibility($path)
{
// TODO: Implement getVisibility() method. 七牛云没有此功能
}
/**
* @param $path 待转码文件路径
* @param $rules 转码规则[转码规则说明](https://developer.qiniu.com/kodo/kb/5858/the-instructions-on-the-storage-space-of-transcoding-style)
* @param null $pipeline 队列名称,若不填写使用TransCoder初始化的pipeline https://portal.qiniu.com/dora/mps/new
* @param null $notifyUrl 处理完毕通知地址,若不填写使用TransCoder初始化的bucket
* @param null $saveAs 保存全部路径,若不填写则为$path的名称加_trans
* @param null $bucket 处理完成保存到bucket若不填写则使用TransCoder初始化的bucket
*
* @return array|string
*
* @throws QiNiuOssAdapterException
*/
public function transCoding($path, $rules, $saveAs = null, $notifyUrl = null, $pipeline = null, $toBucket = null)
{
$dir = '';
$filename = $path;
$position = strripos($path, '/');
if (false !== $position) {
$dir = substr($path, 0, $position + 1);
$filename = substr(strrchr($path, '/'), 1);
}
if (!$saveAs) {
list($name, $ext) = explode('.', $filename);
$saveAs = $dir.$name.'_trans.'.$ext;
}
$toBucket = $toBucket ?: $this->bucket;
$fops = $this->buildTransCodeFop($rules, $toBucket, $saveAs);
$response = $this->getFopManager()->execute($this->bucket, $path, $fops, $pipeline, $notifyUrl);
$this->ossResponse($response);
return $response;
}
public function vframe($path, AbstractVFramePolicy $policy){
$rules = sprintf('vframe/%s/offset/%d/w/%d/h/%d/rotate/%s',
$policy->getFormat(),
$policy->getOffset(),
$policy->getWidth(),
$policy->getHeight(),
$policy->getRotate()
);
$response = $this->getFopManager()->execute($this->bucket, $path, $rules, $policy->getPipeLine(), $policy->getNotifyUrl());
$this->ossResponse($response);
return $response;
}
/**
* @param string $baseUrl 请求url
* @param bool $isBucketPrivate bucket是否为私有如果是私有m3u8文件会对相关ts文件进行授权处理(https://developer.qiniu.com/dora/api/1292/private-m3u8-pm3u8)
* @param int $expires
*
* @return string
*/
public function privateDownloadUrl($baseUrl, $isBucketPrivate = false, $expires = 3600)
{
if (0 !== strpos($baseUrl, 'http')) {
$baseUrl = $this->host.$baseUrl;
}
if ($isBucketPrivate && strstr($baseUrl, 'm3u8')) {
if (strstr($baseUrl, '?')) {
$baseUrl .= '&pm3u8/0';
} else {
$baseUrl .= '?pm3u8/0';
}
}
return $this->auth->privateDownloadUrl($baseUrl, $expires);
}
public function makeBucket($bucket, $region = 'z0'){
$response = $this->getBucketManager()->createBucket($bucket, $region);
$this->ossResponse($response);
return $response;
}
public function fetchBucket($bucket){
$response = $this->getBucketManager()->bucketInfo($bucket);
$this->ossResponse($response);
return $response;
}
protected function buildTransCodeFop($rules, $toBucket, $saveAs){
if (0 !== stripos($rules, 'avthumb/')){
$rules = 'avthumb/'.$rules;
}
$fops = "$rules|saveas/".base64_urlSafeEncode($toBucket.":$saveAs");
return $fops;
}
/**
* @return BucketManager
*/
public function getBucketManager()
{
if (!$this->bucketManager) {
$this->bucketManager = new BucketManager($this->auth);
}
return $this->bucketManager;
}
/**
* @return UploadManager
*/
protected function getUploadManager()
{
if (!$this->uploadManager) {
$this->uploadManager = new UploadManager();
}
return $this->uploadManager;
}
public function getFopManager()
{
if (!$this->fopManager) {
$this->fopManager = new PersistentFop($this->auth);
}
return $this->fopManager;
}
/**
* @param Error|null $error
*/
protected function createExceptionIfError($error = null)
{
if ($error instanceof Error) {
$e = new QiNiuOssAdapterException($error->message(), $error->code());
throw $e->setResponse($error->getResponse());
}
}
/**
* @param array $response
*
* @throws QiNiuOssAdapterException
*/
protected function ossResponse(array &$response)
{
if ($response[1] instanceof Error) {
$error = $response['1'];
$this->createExceptionIfError($error);
}
$response = $response[0];
}
/**
* @param string $path
*
* @return string
*/
protected function urlEncode($path)
{
return strtr($path, [
' ' => '%20',
]);
}
/**
* @param string $path
* @param array $normalized
*
* @return array
*
* @throws QiNiuOssAdapterException
*/
protected function getFileMeta($path, array $normalized)
{
$response = $this->getBucketManager()->stat($this->bucket, $path);
$this->ossResponse($response);
$normalized['mimetype'] = $response['mimeType'];
$normalized['timestamp'] = (int) ceil($response['putTime'] / 1000 / 10000);
$normalized['size'] = $response['fsize'];
return $normalized;
}
/**
* @param string $path
* @param bool $requireMeta
* @param array $options
*
* @return array|mixed
*
* @throws QiNiuOssAdapterException
*/
protected function mapFileInfo($path, $requireMeta = false, $options = [])
{
$normalized = [
'type' => 'file',
'path' => $path,
];
if ($requireMeta) {
$normalized = $this->getFileMeta($path, $normalized);
}
$normalized = array_merge($normalized, $options);
return $normalized;
}
/**
* @param string $dirname
*
* @return array
*/
protected function mapDirInfo($dirname)
{
return ['path' => $dirname, 'type' => 'dir'];
}
private function makeHost($cdnHost)
{
$host = strripos($cdnHost, '/') + 1 === strlen($cdnHost) ? $cdnHost : $cdnHost.'/';
$this->host = strtolower($host);
if (0 !== strpos($this->host, 'http')) {
$this->host = 'http://'.$this->host;
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Liz\Flysystem\QiNiu;
use Qiniu\Http\Response;
class QiNiuOssAdapterException extends \Exception
{
/**
* @var Response
*/
private $response;
/**
* @return Response
*/
public function getResponse()
{
return $this->response;
}
/**
* @param $response
*
* @return $this
*/
public function setResponse(Response $response)
{
$this->response = $response;
return $this;
}
}