| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886 |
- <?php
- namespace common\helpers;
- use Yii;
- use yii\imagine\Image;
- use yii\web\UploadedFile;
- use yii\web\NotFoundHttpException;
- use yii\helpers\Json;
- use linslin\yii2\curl;
- use common\models\common\Attachment;
- use common\components\uploaddrive\DriveInterface;
- /**
- * 上传辅助类
- *
- * Class UploadHelper
- * @package common\helpers
- * @author qimall
- */
- class UploadHelper
- {
- /**
- * 切片合并缓存前缀
- */
- const PREFIX_MERGE_CACHE = 'upload-file-guid:';
- /**
- * 上传配置
- *
- * @var array
- */
- public $config = [];
- /**
- * 上传路径
- *
- * @var array
- */
- public $paths = [];
- /**
- * 默认取 $_FILE['file']
- *
- * @var string
- */
- public $uploadFileName = 'file';
- /**
- * 上传驱动
- *
- * @var
- */
- protected $drive = 'local';
- /**
- * 拿取需要的数据
- *
- * @var array
- */
- protected $filter = [
- 'thumb',
- 'drive',
- 'chunks',
- 'chunk',
- 'guid',
- 'image',
- 'compress',
- 'width',
- 'height',
- 'md5',
- 'poster',
- 'writeTable',
- 'mall_id'
- ];
- /**
- * 上传文件基础信息
- *
- * @var array
- */
- protected $baseInfo = [
- 'domain_name' => '',
- 'name' => '',
- 'old_name' => '',
- 'width' => '',
- 'height' => '',
- 'size' => 0,
- 'extension' => 'jpg',
- 'url' => '',
- 'merge' => false,
- 'guid' => '',
- 'type' => 'image/jpeg',
- 'thumb_url' => [],
- 'duration' => '', // 视频时长
- ];
- /**
- * 是否切片上传
- *
- * @var bool
- */
- protected $isCut = false;
- /**
- * @var DriveInterface
- */
- protected $uploadDrive;
- /**
- * @var \League\Flysystem\Filesystem
- */
- protected $filesystem;
- /**
- * UploadHelper constructor.
- * @param array $config
- * @param string $type 文件类型
- * @param bool $superaddition 追加写入
- * @throws \Exception
- */
- public function __construct(array $config, $type, $superaddition = false)
- {
- // 过滤数据
- $this->filter($config, $type);
- // 设置文件类型
- $this->type = $type;
- // 初始化上传地址
- $this->initPaths();
- // 判断是否切片上传
- if (isset($this->config['chunks']) && isset($this->config['guid'])) {
- $this->drive = 'local';
- $this->isCut = true;
- }
- $drive = $this->drive;
- $config['superaddition'] = $superaddition;
- $this->uploadDrive = Yii::$app->uploadDrive->$drive($config);
- $this->filesystem = $this->uploadDrive->entity();
- }
- /**
- * 验证文件
- *
- * @throws NotFoundHttpException
- */
- public function verifyFile()
- {
- $file = UploadedFile::getInstanceByName($this->uploadFileName);
- if (!$file) {
- throw new NotFoundHttpException('找不到上传文件');
- }
- if ($file->getHasError()) {
- throw new NotFoundHttpException('上传失败,请检查文件');
- }
- $this->baseInfo['extension'] = $file->getExtension();
- $this->baseInfo['size'] = $file->size;
- empty($this->baseInfo['name']) && $this->baseInfo['name'] = $file->getBaseName();
- $this->baseInfo['old_name'] = $file->baseName;
- $baseInfoName = $this->baseInfo['name'];
- if($file->getExtension() === "mp3"){ // 如果类型是MP3,作特殊处理,因为部分苹果手机用小程序,插件识别不了中文名称的音乐
- $baseInfoName = $this->zhToAbbr($this->baseInfo['name']);
- }
- $this->baseInfo['url'] = $this->paths['relativePath'] . $baseInfoName . '.' . $file->getExtension();
- $this->baseInfo['path_dir'] = $this->paths['relativePath'];
- unset($file);
- $this->verify();
- }
- /**
- * MP3中文转首字母,如“我123”,转为“W123”
- */
- public function zhToAbbr($str){
- $result = '';
- for ($i = 0; $i < mb_strlen($str); $i++) {
- $char = mb_substr($str, $i, 1, 'UTF-8');
- if (preg_match('/[a-zA-Z0-9]/', $char)) {
- $result .= strtoupper($char); // 字母/数字直接保留
- } else {
- $result .= $this->getFirstCharter($char); // 中文转首字母
- }
- }
- return $result.time();
- }
- /**
- * 中文转首字母
- */
- public function getFirstCharter($str) {
- if (empty($str)) { return '';}
- // 静态拼音首字母映射表(GB2312编码区间 → 字母)
- static $pinyinMap = [
- [-20319, -20284, 'A'],[-20283, -19776, 'B'],[-19775, -19219, 'C'],[-19218, -18711, 'D'],[-18710, -18527, 'E'],[-18526, -18240, 'F'],[-18239, -17923, 'G'],
- [-17922, -17418, 'H'],[-17417, -16475, 'J'],[-16474, -16213, 'K'],[-16212, -15641, 'L'],[-15640, -15166, 'M'],[-15165, -14923, 'N'],[-14922, -14915, 'O'],
- [-14914, -14631, 'P'],[-14630, -14150, 'Q'],[-14149, -14091, 'R'],[-14090, -13319, 'S'],[-13318, -12839, 'T'],[-12838, -12557, 'W'],[-12556, -11848, 'X'],
- [-11847, -11056, 'Y'],[-11055, -10247, 'Z'],
- ];
-
- // 如果是A-Z或a-z直接返回大写
- $firstChar = $str[0];
- $fchar = ord($firstChar);
- if (($fchar >= ord('A') && $fchar <= ord('Z')) || ($fchar >= ord('a') && $fchar <= ord('z'))) {
- return strtoupper($firstChar);
- }
-
- // 转换为GB2312编码计算区间
- $s1 = iconv('UTF-8', 'gb2312//IGNORE', $str);
- $s2 = iconv('gb2312', 'UTF-8//IGNORE', $s1);
- $s = ($s2 == $str) ? $s1 : $str;
- if (strlen($s) < 2) { return '';}
- $asc = ord($s[0]) * 256 + ord($s[1]) - 65536;
- // 遍历映射表匹配区间
- foreach ($pinyinMap as $range) {
- if ($asc >= $range[0] && $asc <= $range[1]) {
- return $range[2];
- }
- }
-
- return '';
- }
- /**
- * 验证Url
- *
- * @param $url
- * @return bool
- * @throws NotFoundHttpException
- */
- public function verifyUrl($url)
- {
- $imgUrl = str_replace("&", "&", htmlspecialchars($url));
- // http开头验证
- if (strpos($imgUrl, "http") !== 0) {
- throw new NotFoundHttpException('不是一个http地址');
- }
- preg_match('/(^https?:\/\/[^:\/]+)/', $imgUrl, $matches);
- $host_with_protocol = count($matches) > 1 ? $matches[1] : '';
- // 判断是否是合法 url
- if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
- throw new NotFoundHttpException('Url不合法');
- }
- preg_match('/^https?:\/\/(.+)/', $host_with_protocol, $matches);
- $host_without_protocol = count($matches) > 1 ? $matches[1] : '';
- // 此时提取出来的可能是 IP 也有可能是域名,先获取 IP
- $ip = gethostbyname($host_without_protocol);
- // 获取请求头并检测死链
- $heads = get_headers($imgUrl, 1);
- if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
- throw new NotFoundHttpException('文件获取失败');
- }
- // Content-Type验证
- if (!isset($heads['Content-Type']) || !stristr($heads['Content-Type'], "image")) {
- throw new NotFoundHttpException('格式验证失败');
- }
- $extend = StringHelper::clipping($imgUrl, '.', 1);
- if (!in_array($extend, Yii::$app->params['uploadConfig']['images']['extensions'])) {
- $extend = 'jpg';
- }
- $curl = new curl\Curl();
- $img = $curl->get($imgUrl);
- $this->baseInfo['extension'] = $extend;
- $this->baseInfo['size'] = strlen($img);
- $this->config['md5'] = md5($img);
- $this->baseInfo['url'] = $this->paths['relativePath'] . $this->baseInfo['name'] . '.' . $extend;
- $this->verify();
- return $img;
- }
- /**
- * 验证base64格式的内容
- *
- * @param $data
- * @param $extend
- * @throws NotFoundHttpException
- */
- public function verifyBase64($data, $extend)
- {
- $this->baseInfo['extension'] = $extend;
- $this->baseInfo['size'] = strlen($data);
- $this->baseInfo['url'] = $this->paths['relativePath'] . $this->baseInfo['name'] . '.' . $extend;
- $this->verify();
- unset($data, $extend);
- }
- /**
- * 验证文件大小及类型
- *
- * @throws NotFoundHttpException
- */
- protected function verify()
- {
- if ($this->baseInfo['size'] > $this->config['maxSize'] && $this->config['maxSize'] > 0) {
- throw new NotFoundHttpException('文件大小超出网站限制');
- }
- if (!empty($this->config['extensions']) && !in_array($this->baseInfo['extension'],
- $this->config['extensions'])) {
- throw new NotFoundHttpException('文件类型不允许');
- }
- // 存储本地进行安全校验
- if ($this->drive == Attachment::DRIVE_LOCAL) {
- if ($this->type == Attachment::UPLOAD_TYPE_FILES && in_array($this->baseInfo['extension'],
- $this->config['blacklist'])) {
- throw new NotFoundHttpException('上传的文件类型不允许');
- }
- }
- }
- /**
- * 写入
- *
- * @param bool $data
- * @throws NotFoundHttpException
- * @throws \League\Flysystem\FileExistsException
- * @throws \League\Flysystem\FileNotFoundException
- */
- public function save($data = false)
- {
- // 获取域名
- $this->baseInfo = $this->uploadDrive->getDomainName($this->baseInfo, $this->drive, $this->config['fullPath']);
- // 拦截 如果是切片上传就接管
- if ($this->isCut == true) {
- $this->cut();
- return;
- }
- // 判断如果文件存在就重命名文件名
- // if ($this->filesystem->has($this->baseInfo['url'])) {
- // $name = explode('_', $this->baseInfo['name']);
- // $this->baseInfo['name'] = $name[0] . '_' . time() . '_' . StringHelper::random(8);
- // $this->baseInfo['url'] = $this->paths['relativePath'] . $this->baseInfo['name'] . '.' . $this->baseInfo['extension'];
- // }
- // 视频上传获取封面图
- if ($this->type == Attachment::UPLOAD_TYPE_VIDEOS) {
- // $this->getVideoPoster();
- $this->getVideoInfo();
- }
- // 判断是否直接写入
- if (false === $data) {
- $file = UploadedFile::getInstanceByName($this->uploadFileName);
- if (!$file->getHasError()) {
- $stream = fopen($file->tempName, 'r+');
- $result = Yii::$app->uploadDrive->local([])->entity()->writeStream($this->baseInfo['url'], $stream);
- $this->compress();
- if($this->drive != 'local'){
- $stream = fopen(Yii::getAlias("@attachment/") . $this->baseInfo['url'], 'r+');
- $result = $this->filesystem->writeStream($this->baseInfo['url'], $stream);
- unlink(Yii::getAlias("@attachment/") . $this->baseInfo['url']);
- }
- if (!$result) {
- throw new NotFoundHttpException('文件写入失败');
- }
- if (is_resource($stream)) {
- fclose($stream);
- }
- } else {
- throw new NotFoundHttpException('上传失败,可能文件太大了');
- }
- } else {
- $result = $this->filesystem->write($this->baseInfo['url'], $data);
- if (!$result) {
- throw new NotFoundHttpException('文件写入失败');
- }
- }
- // 本地的图片才可执行
- if ($this->type == 'images' && $this->drive == 'local') {
- // 图片水印
- $this->watermark();
- // 图片压缩
- $this->compress();
- // 创建缩略图
- $this->thumb();
- // 获取图片信息
- if (empty($this->baseInfo['width']) && empty($this->baseInfo['height']) && $this->filesystem->has($this->baseInfo['url'])) {
- $imgInfo = getimagesize(Yii::getAlias('@attachment') . '/' . $this->baseInfo['url']);
- $this->baseInfo['width'] = $imgInfo[0] ?? 0;
- $this->baseInfo['height'] = $imgInfo[1] ?? 0;
- }
- }
- return;
- }
- /**
- * 获取视频封面图
- *
- * @return bool
- * @throws \League\Flysystem\FileExistsException
- * @throws NotFoundHttpException
- */
- public function getVideoPoster()
- {
- // use `ffmpeg` get first frame as video poster
- // save poster local and upload to cloud, return the cloud url
- $file = UploadedFile::getInstanceByName($this->uploadFileName);
- if ($file->error === UPLOAD_ERR_OK) {
- $this->type = Attachment::UPLOAD_TYPE_IMAGES;
- $name = $this->baseInfo['name'];
- $this->baseInfo['name'] = $this->baseInfo['name'] . '_poster';
- $extension = $this->baseInfo['extension'];
- $url = $this->baseInfo['url'];
- $this->baseInfo['extension'] = 'jpg';
- $this->baseInfo['url'] = $this->paths['relativePath'] . $this->baseInfo['name'] . '.' . $this->baseInfo['extension'];
- $tmpPosterFilePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $this->baseInfo['name'] . '.' . $this->baseInfo['extension'];
- FfmpegHelper::imageResize($file->tempName, $tmpPosterFilePath, 1);
- if (file_exists($tmpPosterFilePath)) {
- $stream = fopen($tmpPosterFilePath, 'r+');
- $result = $this->filesystem->writeStream($this->baseInfo['url'], $stream);
- if (!$result) {echo '文件写入失败';
- throw new NotFoundHttpException('文件写入失败');
- }
- if (is_resource($stream)) {
- fclose($stream);
- }
- $imgInfo = getimagesize($tmpPosterFilePath);
- $this->baseInfo['width'] = $imgInfo[0] ?? 0;
- $this->baseInfo['height'] = $imgInfo[1] ?? 0;
- unlink($tmpPosterFilePath); // delete tmp file
- // 还原
- $this->type = Attachment::UPLOAD_TYPE_VIDEOS;
- $this->baseInfo['thumb_url'][] = $this->baseInfo['domain_name'] . $this->baseInfo['url'];
- $this->baseInfo['url'] = $url;
- $this->baseInfo['name'] = $name;
- $this->baseInfo['extension'] = $extension;
- return true;
- }
- }
- return false;
- }
- /**
- * @name:
- * @msg: 获取视频时长
- * @param {*}
- * @return {*}
- */
- public function getVideoInfo()
- {
- $file = UploadedFile::getInstanceByName($this->uploadFileName);
- if ($file->error === UPLOAD_ERR_OK) {
- $tmp_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $this->baseInfo['name'] . '.' . $this->baseInfo['extension'];
- copy($file->tempName, $tmp_file);
- $video_info = FfmpegHelper::getVideoInfo($tmp_file);
- // dd($video_info);
- $this->baseInfo['duration_str'] = $video_info['duration']??'0';
- $this->baseInfo['duration_seconds'] = $video_info['seconds']??'0';
- @unlink($tmp_file);
- }
- }
- /**
- * 水印
- *
- * @param $fullPathName
- * @return bool
- */
- protected function watermark()
- {
- return true;
- if (Yii::$app->debris->backendConfig('sys_image_watermark_status') != true) {
- return true;
- }
- // 原图路径
- $absolutePath = Yii::getAlias("@attachment/") . $this->baseInfo['url'];
- $local = Yii::$app->debris->backendConfig('sys_image_watermark_location');
- $watermarkImg = StringHelper::getLocalFilePath(Yii::$app->debris->backendConfig('sys_image_watermark_img'));
- if ($coordinate = DebrisHelper::getWatermarkLocation($absolutePath, $watermarkImg, $local)) {
- // $aliasName = StringHelper::getAliasUrl($fullPathName, 'watermark');
- Image::watermark($absolutePath, $watermarkImg, $coordinate)
- ->save($absolutePath, ['quality' => 100]);
- }
- return true;
- }
- /**
- * 压缩
- *
- * @param $fullPathName
- * @return bool
- */
- protected function compress()
- {
- $compress = false;
- $mall_id = $this->config['mall_id']??0;
- $mall_limit = \Yii::$app->services->setting->mall->get($mall_id,'limit');
- if(!empty($mall_limit['upload_images_compress'])){
- $compress = true;
- }
- if ($compress != true) {
- return true;
- }
- // 原图路径
- $absolutePath = Yii::getAlias("@attachment/") . $this->baseInfo['url'];
- $imgInfo = getimagesize($absolutePath);
- $compressibility = $this->config['compressibility'];
- $tmpMinSize = 0;
- if (empty($compressibility)) return true;
- foreach ($compressibility as $key => $item) {
- if ($this->baseInfo['size'] >= $tmpMinSize && $this->baseInfo['size'] < $key && $item < 100) {
- // $aliasName = StringHelper::getAliasUrl($fullPathName, 'compress');
- if($imgInfo['mime']=='image/png'){
- $imgInfo[0] = ($item+10)/100*$imgInfo[0];
- $imgInfo[1] = ($item+10)/100*$imgInfo[1];
- }
- Image::thumbnail($absolutePath, $imgInfo[0], $imgInfo[1])
- ->save($absolutePath, ['quality' => $item]);
- break;
- }
- $tmpMinSize = $key;
- }
- return true;
- }
- /**
- * 缩略图
- *
- * @return bool
- */
- protected function thumb()
- {
- if (empty($this->config['thumb'])) {
- \Yii::error('thumb empty');
- return true;
- }
- // 原图路径
- $absolutePath = Yii::getAlias("@attachment/") . $this->baseInfo['url'];
- // 缩略图路径
- $path = Yii::getAlias("@attachment/") . $this->paths['thumbRelativePath'];
- FileHelper::mkdirs($path);
- $thumbPath = $path . $this->baseInfo['name'] . '.' . $this->baseInfo['extension'];
- foreach ($this->config['thumb'] as $value) {
- $thumbFullPath = StringHelper::createThumbUrl($thumbPath, $value['width'], $value['height']);
- // 裁剪从坐标0,60 裁剪一张300 x 20 的图片,并保存 不设置坐标则从坐标0,0开始
- // Image::crop($originalPath, $thumbWidth , $thumbHeight, [0, 60])->save($thumbOriginalPath), ['quality' => 100]);
- Image::thumbnail($absolutePath, $value['width'], $value['height'])->save($thumbFullPath);
- $this->baseInfo['thumb_url'][] = $thumbFullPath;
- }
- return true;
- }
- /**
- * 切片
- *
- * @throws \League\Flysystem\FileExistsException
- * @throws \League\Flysystem\FileNotFoundException
- */
- public function cut()
- {
- // 切片参数
- $chunk = $this->config['chunk'] + 1;
- $guid = $this->config['guid'];
- // 临时文件夹路径
- $url = $this->paths['tmpRelativePath'] . $chunk . '.' . $this->baseInfo['extension'];
- // 上传
- $file = UploadedFile::getInstanceByName($this->uploadFileName);
- if ($file->error === UPLOAD_ERR_OK) {
- $stream = fopen($file->tempName, 'r+');
- $result = $this->filesystem->writeStream($url, $stream);
- fclose($stream);
- // 判断如果上传成功就去合并文件
- $this->baseInfo['chunk'] = $chunk;
- if ($this->config['chunks'] == $chunk) {
- // 缓存上传信息等待回调
- Yii::$app->cache->set(self::PREFIX_MERGE_CACHE . $guid, [
- 'type' => $this->type,
- 'drive' => $this->drive,
- 'paths' => $this->paths,
- 'baseInfo' => $this->baseInfo,
- 'config' => $this->config,
- ], 3600);
- }
- $this->baseInfo['merge'] = true;
- $this->baseInfo['guid'] = $guid;
- }
- }
- /**
- * 切片合并
- *
- * @param int $name
- * @throws \League\Flysystem\FileExistsException
- * @throws \League\Flysystem\FileNotFoundException
- */
- public function merge($name = 1)
- {
- // 由于合并会附带上一次切片的信息,取消切片判断
- $this->isCut = false;
- $filePath = $this->paths['tmpRelativePath'] . $name . '.' . $this->baseInfo['extension'];
- if ($this->filesystem->has($filePath) && ($content = $this->filesystem->read($filePath))) {
- if ($this->filesystem->has($this->baseInfo['url'])) {
- $this->filesystem->update($this->baseInfo['url'], $content);
- } else {
- $this->filesystem->write($this->baseInfo['url'], $content);
- }
- unset($content);
- $this->filesystem->delete($filePath);
- $name += 1;
- self::merge($name);
- } else {
- // 删除文件夹,如果删除失败重新去合并
- $this->filesystem->deleteDir($this->paths['tmpRelativePath']);
- }
- }
- /**
- * 获取生成路径信息
- *
- * @return array
- */
- protected function initPaths()
- {
- if (!empty($this->paths)) {
- return $this->paths;
- }
- $config = $this->config;
- // 保留原名称
- $config['originalName'] == false && $this->baseInfo['name'] = $config['prefix'] . time() . '_' . StringHelper::random(8);
- // 文件路径
- $mall_config = !empty($config['mall_id']) ? $config['mall_id'] . '/' : '';
- $filePath = $config['path'] . $mall_config . date($config['subName'], time()) . "/";
- // 缩略图
- $thumbPath = Yii::$app->params['uploadConfig']['thumb']['path'] . $config['mall_id'] . '/' . date($config['subName'], time()) . "/";
- empty($config['guid']) && $config['guid'] = StringHelper::random(8);
- $tmpPath = 'tmp/' . $config['mall_id'] . '/' . date($config['subName'], time()) . "/" . $config['guid'] . '/';
- $this->paths = [
- 'relativePath' => $filePath, // 相对路径
- 'thumbRelativePath' => $thumbPath, // 缩略图相对路径
- 'tmpRelativePath' => $tmpPath, // 临时相对路径
- ];
- return $this->paths;
- }
- /**
- * 过滤数据
- *
- * @param $config
- */
- protected function filter($config, $type)
- {
- $mall_id = $config['mall_id'];
- try {
- // 解密json
- foreach ($config as $key => &$item) {
- if (!empty($item) && !is_numeric($item) && !is_array($item)) {
- !empty(json_decode($item)) && $item = Json::decode($item);
- }
- }
- $config = ArrayHelper::filter($config, $this->filter);
- $this->config = ArrayHelper::merge(Yii::$app->params['uploadConfig'][$type], $config);
- // 参数
- $this->baseInfo['width'] = $this->config['width'] ?? 0;
- $this->baseInfo['height'] = $this->config['height'] ?? 0;
- } catch (\Exception $e) {
- $this->config = Yii::$app->params['uploadConfig'][$type];
- }
- !empty($this->config['drive']) && $this->drive = $this->config['drive'];
- $platform_limit = \Yii::$app->services->setting->platform->get('limit');
- $mall_limit = \Yii::$app->services->setting->mall->get($mall_id,'limit');
- switch ($type){
- case 'videos':
- $upload_type = 'video';
- break;
- case 'images':
- $upload_type = 'img';
- break;
- }
- if(isset($upload_type)){
- if(!empty($mall_limit[$upload_type])){
- $this->config['maxSize'] = $mall_limit[$upload_type]*1024 * 1024;
- }else{
- if(!empty($platform_limit[$upload_type])){
- $this->config['maxSize'] = $platform_limit[$upload_type]*1024 * 1024;
- }
- }
- }
- }
- /**
- * 写入目录
- *
- * @param array $paths
- */
- public function setPaths(array $paths)
- {
- $this->paths = $paths;
- }
- /**
- * 写入基础信息
- *
- * @param array $baseInfo
- */
- public function setBaseInfo(array $baseInfo)
- {
- $this->baseInfo = $baseInfo;
- }
- /**
- * @param mixed $drive
- */
- public function setDrive($drive)
- {
- $this->drive = $drive;
- }
- /**
- * @return array
- * @throws NotFoundHttpException
- * @throws \League\Flysystem\FileNotFoundException
- */
- public function getBaseInfo($mall_id,$mch_id=0,$group_id=0,$store_id=0,$addons_name='')
- {
- // 是否切片
- if ($this->isCut == true) {
- return $this->baseInfo;
- }
- // 处理上传的文件信息
- $this->baseInfo['type'] = $this->filesystem->getMimetype($this->baseInfo['url']);
- $this->baseInfo['size'] = $this->filesystem->getSize($this->baseInfo['url']);
- $this->baseInfo['url'] = $this->baseInfo['domain_name'] . $this->baseInfo['url'];
- $path = $this->baseInfo['url'];
- $data = [
- 'mall_id' => $mall_id,
- 'mch_id' => $mch_id,
- 'group_id' => $group_id,
- 'store_id' => $store_id,
- 'drive' => $this->drive,
- 'upload_type' => $this->type,
- 'size' => $this->baseInfo['size'],
- 'width' => $this->baseInfo['width'],
- 'height' => $this->baseInfo['height'],
- 'extension' => $this->baseInfo['extension'],
- 'name' => $this->baseInfo['name'],
- 'old_name' => $this->baseInfo['old_name'],
- 'md5' => $this->config['md5'] ?? '',
- 'url' => $this->baseInfo['url'],
- 'path' => $path,
- 'thumb_url' => !empty($this->baseInfo['thumb_url']) ? implode(',',$this->baseInfo['thumb_url']) : '',
- 'duration_str' => $this->baseInfo['duration_str'] ?? '',
- 'duration_seconds' => $this->baseInfo['duration_seconds'] ?? 0,
- 'addons_name' => $addons_name
- ];
- //阿里云oss 设置了cdn:修改图片地址为cdn
- $oss_cdn = \Yii::$app->params['oss_cdn'] ?? '';
- if($oss_cdn && $this->drive == Attachment::DRIVE_OSS){
- //替换oss 地址 => cdn 地址
- $data['url'] = str_replace($this->baseInfo['domain_name'],$oss_cdn,$data['url']);
- $data['path'] = str_replace($this->baseInfo['domain_name'],$oss_cdn,$data['path']);
- $this->baseInfo['url'] = $data['url'];
- }
- // 写入数据库
- $attachment_id = Yii::$app->services->attachment->create($data);
- $this->baseInfo['id'] = $attachment_id;
- $this->baseInfo['formatter_size'] = Yii::$app->formatter->asShortSize($this->baseInfo['size'], 2);
- $this->baseInfo['upload_type'] = self::formattingFileType($this->baseInfo['type'], $this->baseInfo['extension'], $this->type);
- return $this->baseInfo;
- }
- /**
- * @param $specific_type
- * @param $extension
- * @return string
- */
- public static function formattingFileType($specific_type, $extension, $upload_type)
- {
- if (preg_match("/^image/", $specific_type) && $extension != 'psd') {
- return Attachment::UPLOAD_TYPE_IMAGES;
- }
- return $upload_type;
- }
- /**
- * 删除文件
- * @param $path
- * @throws
- * @return
- */
- public function delete($path)
- {
- return $this->filesystem->delete($path);
- }
- /**
- * 本地上传
- * @Author: hua
- * @DateTime: 2021/10/14 10:30
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $relative_filename //相对路径资源
- * @return mixed|void
- * @throws NotFoundHttpException
- * @throws \League\Flysystem\FileExistsException
- * @throws \League\Flysystem\FileNotFoundException
- */
- public function upload($relative_filename)
- {
- $file = Yii::getAlias('@attachment') . '/' .$relative_filename;
- $path_info = pathinfo($file);
- $this->paths['extension'] = $path_info['extension'];
- $this->baseInfo['url'] = $relative_filename;
- $stream = fopen($file, 'r+');
- $result = $this->filesystem->writeStream($this->baseInfo['url'], $stream);
- if (!$result) {
- throw new NotFoundHttpException('文件写入失败');
- }
- if (is_resource($stream)) {
- fclose($stream);
- }
- return $this->baseInfo['url'];
- }
- }
|