diff --git a/composer.json b/composer.json index 03443d1..e78dace 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,13 @@ { - "name": "jacobcyl/ali-oss-storage", + "name": "summergeorge/ali-oss-storage", "description": "aliyun oss filesystem storage for laravel 5+", "keywords": ["aliyun", "oss", "laravel", "filesystems", "storage"], - "homepage": "http://jacobcyl.github.io/Aliyun-oss-storage/", + "homepage": "https://github.com/summergeorge/Aliyun-oss-storage", "license": "MIT", "authors": [ { - "name": "jacobcyl", - "email": "cyl.jacob@gmail.com" + "name": "summergeorge", + "email": "qihao201net@126.com" } ], "require": { diff --git a/readme.md b/readme.md index 599fd49..1576a2f 100644 --- a/readme.md +++ b/readme.md @@ -1,23 +1,40 @@ +> 如果本项目对您有帮助且愿意花时间一起维护,欢迎提交PR,我将每个月做一次PR合并。 + +> 如果您想和我一起维护,欢迎发邮件给我,我将把您加为项目协作者。 # Aliyun-oss-storage for Laravel 5+ +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/summergeorge/Aliyun-oss-storage/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/summergeorge/Aliyun-oss-storage/?branch=master) +[![Build Status](https://scrutinizer-ci.com/g/summergeorge/Aliyun-oss-storage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/summergeorge/Aliyun-oss-storage/build-status/master) +[![Latest Stable Version](https://poser.pugx.org/summergeorge/ali-oss-storage/v/stable)](https://packagist.org/packages/summergeorge/ali-oss-storage) +[![Total Downloads](https://poser.pugx.org/summergeorge/ali-oss-storage/downloads)](https://packagist.org/packages/summergeorge/ali-oss-storage) +[![Latest Unstable Version](https://poser.pugx.org/summergeorge/ali-oss-storage/v/unstable)](https://packagist.org/packages/summergeorge/ali-oss-storage) +[![License](https://poser.pugx.org/summergeorge/ali-oss-storage/license)](https://packagist.org/packages/summergeorge/ali-oss-storage) + +--- + Aliyun oss filesystem storage adapter for laravel 5. You can use Aliyun OSS just like laravel Storage as usual. 借鉴了一些优秀的代码,综合各方,同时做了更多优化,将会添加更多完善的接口和插件,打造Laravel最好的OSS Storage扩展 + + ## Inspired By - [thephpleague/flysystem-aws-s3-v2](https://github.com/thephpleague/flysystem-aws-s3-v2) - [apollopy/flysystem-aliyun-oss](https://github.com/apollopy/flysystem-aliyun-oss) +- [jacobcyl/Aliyun-oss-storage](https://github.com/jacobcyl/Aliyun-oss-storage) ## Require - Laravel 5+ - cURL extension -##Installation +之前 fork 的 [jacobcyl/Aliyun-oss-storage](https://github.com/jacobcyl/Aliyun-oss-storage) ,自2.1.1版本开始,增加新功能,更改 composer 包名称为:`summergeorge/ali-oss-storage` + +## Installation In order to install AliOSS-storage, just add - "jacobcyl/ali-oss-storage": "^2.1" + "summergeorge/ali-oss-storage": "^2.2" to your composer.json. Then run `composer install` or `composer update`. Or you can simply run below command to install: - "composer require jacobcyl/ali-oss-storage:^2.1" + "composer require summergeorge/ali-oss-storage:^2.2" Then in your `config/app.php` add this line to providers array: ```php @@ -34,7 +51,7 @@ Add the following in app/filesystems.php: 'access_key' => '', 'bucket' => '', 'endpoint'     => '', // OSS 外网节点或自定义外部域名 -            //'endpoint_internal' => '', // v2.0.4 新增配置属性,如果为空,则默认使用 endpoint 配置(由于内网上传有点小问题未解决,请大家暂时不要使用内网节点上传,正在与阿里技术沟通中) +            'endpoint_internal' => '', // v2.2.1 新增配置属性,如果为空,则默认使用 endpoint 配置。 'cdnDomain'     => '', // 如果isCName为true, getUrl会判断cdnDomain是否设定来决定返回的url,如果cdnDomain未设置,则使用endpoint来生成url,否则使用cdn 'ssl'           => // true to use 'https://' and false to use 'http://'. default is false, 'isCName'       => // 是否使用自定义域名,true: 则Storage.url()会使用自定义的cdn或域名生成文件url, false: 则使用外部节点生成url @@ -96,6 +113,15 @@ Storage::deleteDirectory($directory); // Recursively delete a directory.It will Storage::putRemoteFile('target/path/to/file/jacob.jpg', 'http://example.com/jacob.jpg'); //upload remote file to storage by remote url // new function for v2.0.1 version Storage::url('path/to/img.jpg') // get the file url +// new function for v2.1.1 version +Storage::signUrl('path/to/img.jpg',$timeout) //(请使用新的temporaryUrl方法) get the file url with signature,default timeout = 600 +// new function for v2.1.4 version +Storage::temporaryUrl('path/to/img.jpg',$timeout) // get the file url with signature,default timeout = 600 + +// new function for v2.1.2 version +// 阿里云 oss 帮助文档:https://help.aliyun.com/document_detail/44688.html?spm=a2c4g.11186623.6.1199.40572e934MoHWu +// getProcessUrl(图片在 oss 中的路径,操作名称(例如:resize),参数(key => value 形式的数组)); +Storage::getProcessUrl('path/to/img.jpg','resize', ['m' => 'fixed','h' => '100','w' => '100']) // picture processing,处理图片,支持 oss 图片处理的功能 ``` ## Documentation diff --git a/src/AliOssAdapter.php b/src/AliOssAdapter.php index 54d8703..293ea05 100644 --- a/src/AliOssAdapter.php +++ b/src/AliOssAdapter.php @@ -7,7 +7,7 @@ namespace Jacobcyl\AliOSS; -use Dingo\Api\Contract\Transformer\Adapter; +use Illuminate\Support\Arr; use League\Flysystem\Adapter\AbstractAdapter; use League\Flysystem\AdapterInterface; use League\Flysystem\Config; @@ -15,7 +15,7 @@ use OSS\Core\OssException; use OSS\OssClient; use Log; -use Symfony\Component\Filesystem\Exception\FileNotFoundException; +use Illuminate\Contracts\Filesystem\FileNotFoundException; class AliOssAdapter extends AbstractAdapter { @@ -67,7 +67,7 @@ class AliOssAdapter extends AbstractAdapter protected $bucket; protected $endPoint; - + protected $cdnDomain; protected $ssl; @@ -449,12 +449,16 @@ public function read($path) public function readStream($path) { $result = $this->readObject($path); - $result['stream'] = $result['raw_contents']; + if (is_resource($result['raw_contents'])) { + $result['stream'] = $result['raw_contents']; + $result['raw_contents']->detachStream(); + } else { + $result['stream'] = fopen('php://temp', 'r+'); + fwrite($result['stream'], $result['raw_contents']); + } rewind($result['stream']); // Ensure the EntityBody object destruction doesn't close the stream - $result['raw_contents']->detachStream(); unset($result['raw_contents']); - return $result; } @@ -549,7 +553,7 @@ public function getVisibility($path) $this->logErr(__FUNCTION__, $e); return false; } - + if ($acl == OssClient::OSS_ACL_TYPE_PUBLIC_READ ){ $res['visibility'] = AdapterInterface::VISIBILITY_PUBLIC; }else{ @@ -567,10 +571,37 @@ public function getVisibility($path) */ public function getUrl( $path ) { - if (!$this->has($path)) throw new FileNotFoundException($filePath.' not found'); + if (!$this->has($path)) throw new FileNotFoundException($path.' not found'); return ( $this->ssl ? 'https://' : 'http://' ) . ( $this->isCname ? ( $this->cdnDomain == '' ? $this->endPoint : $this->cdnDomain ) : $this->bucket . '.' . $this->endPoint ) . '/' . ltrim($path, '/'); } + + /** + * @param $path + * @param $expire + * @param $options + * @return string + * @throws FileNotFoundException + * @throws OssException + */ + public function getTemporaryUrl($path, $expire = 600, $options) { + if (!$this->has($path)) + throw new FileNotFoundException($path.' not found'); + $method = OssClient::OSS_HTTP_GET; + if (Arr::has($options, OssClient::OSS_METHOD)) { + $method = $options['method']; + } + return $this->getClient() + ->signUrl( + $this->getBucket(), + $path, + $expire, + $method, + $options + ); + } + + /** * The the ACL visibility. * @@ -608,7 +639,7 @@ protected function normalizeResponse(array $object, $path = null) return $result; } - + $result = array_merge($result, Util::map($object, static::$resultMap), ['type' => 'file']); return $result; @@ -629,7 +660,7 @@ protected function getOptions(array $options = [], Config $config = null) $options = array_merge($options, $this->getOptionsFromConfig($config)); } - return array(OssClient::OSS_HEADERS => $options); + return $options; } /** diff --git a/src/AliOssServiceProvider.php b/src/AliOssServiceProvider.php index c3ac755..0a0e986 100644 --- a/src/AliOssServiceProvider.php +++ b/src/AliOssServiceProvider.php @@ -4,6 +4,8 @@ use Jacobcyl\AliOSS\Plugins\PutFile; use Jacobcyl\AliOSS\Plugins\PutRemoteFile; +use Jacobcyl\AliOSS\Plugins\SignUrl; +use Jacobcyl\AliOSS\Plugins\GetProcessUrl; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Log; use Illuminate\Support\ServiceProvider; @@ -36,23 +38,30 @@ public function boot() $cdnDomain = empty($config['cdnDomain']) ? '' : $config['cdnDomain']; $bucket = $config['bucket']; - $ssl = empty($config['ssl']) ? false : $config['ssl']; + $ssl = empty($config['ssl']) ? false : $config['ssl']; $isCname = empty($config['isCName']) ? false : $config['isCName']; + $securityToken = empty($config['securityToken']) ? null : $config['securityToken']; $debug = empty($config['debug']) ? false : $config['debug']; $endPoint = $config['endpoint']; // 默认作为外部节点 - $epInternal= $isCname?$cdnDomain:(empty($config['endpoint_internal']) ? $endPoint : $config['endpoint_internal']); // 内部节点 + // $epInternal= $isCname?$cdnDomain:(empty($config['endpoint_internal']) ? $endPoint : $config['endpoint_internal']); // 内部节点 + $epInternal= (empty($config['endpoint_internal']) ? $endPoint : $config['endpoint_internal']); // 内部节点 if($debug) Log::debug('OSS config:', $config); - $client = new OssClient($accessId, $accessKey, $epInternal, $isCname); + $client = new OssClient($accessId, $accessKey, $epInternal, $isCname, $securityToken); $adapter = new AliOssAdapter($client, $bucket, $endPoint, $ssl, $isCname, $debug, $cdnDomain); //Log::debug($client); $filesystem = new Filesystem($adapter); - + $filesystem->addPlugin(new PutFile()); $filesystem->addPlugin(new PutRemoteFile()); + //增加使用签名URL进行临时授权 + $filesystem->addPlugin(new SignUrl()); + + //增加图片处理的方法 + $filesystem->addPlugin(new GetProcessUrl()); //$filesystem->addPlugin(new CallBack()); return $filesystem; }); diff --git a/src/Plugins/GetProcessUrl.php b/src/Plugins/GetProcessUrl.php new file mode 100644 index 0000000..c4694f3 --- /dev/null +++ b/src/Plugins/GetProcessUrl.php @@ -0,0 +1,50 @@ + 'fixed','h' => '100','w' => '100']){ + if(empty($action) || empty($option)){ + throw new \Exception('操作名称和操作参数不能为空!'); + } + + $url = $this->filesystem->getAdapter()->getUrl($path); + + $param = ''; + foreach ($option as $key => $value){ + $param .= ','.$key.'_'.$value; + } + + return $url.'?x-oss-process=image/'.$action.$param; + } +} diff --git a/src/Plugins/PutFile.php b/src/Plugins/PutFile.php index d09d0d4..e1d1add 100644 --- a/src/Plugins/PutFile.php +++ b/src/Plugins/PutFile.php @@ -8,7 +8,6 @@ namespace Jacobcyl\AliOSS\Plugins; -use Illuminate\Support\Facades\Log; use League\Flysystem\Config; use League\Flysystem\Plugin\AbstractPlugin; @@ -30,7 +29,7 @@ public function handle($path, $filePath, array $options = []){ if (method_exists($this->filesystem, 'getConfig')) { $config->setFallback($this->filesystem->getConfig()); } - + return (bool)$this->filesystem->getAdapter()->writeFile($path, $filePath, $config); } -} \ No newline at end of file +} diff --git a/src/Plugins/SignUrl.php b/src/Plugins/SignUrl.php new file mode 100644 index 0000000..e4bec61 --- /dev/null +++ b/src/Plugins/SignUrl.php @@ -0,0 +1,31 @@ +filesystem->getAdapter()->has($path)) throw new FileNotFoundException($path.' not found'); + return $this->filesystem->getAdapter()->getClient()->signUrl($this->filesystem->getAdapter()->getBucket(),$path,$timeout); + } +}