Files
premium/extend/laytp/library/UploadDomain.php
T
2025-05-18 07:42:27 +00:00

261 lines
9.4 KiB
PHP
Executable File

<?php
namespace laytp\library;
use app\model\Files;
use app\service\ConfServiceFacade;
use laytp\traits\Error;
use think\facade\Config;
use think\facade\Env;
/**
* 上传文件域名前缀处理类
*/
class UploadDomain
{
use Error;
/**
* 检测上传的文件
* @param $fileName
* @param $fileSize
* @param $fileExt
* @param $fileMime
* @return bool
*/
public function check($fileName, $fileSize, $fileExt, $fileMime)
{
$allowSize = request()->param('size', ConfServiceFacade::get('system.upload.size'));
if (!$this->checkSize($fileSize, $allowSize)) {
return false;
}
$allowExt = request()->param('mime', ConfServiceFacade::get('system.upload.mime'));
if (!$this->checkExt($fileName, $fileExt, $allowExt)) {
return false;
}
if (!$this->checkMime($fileMime)) {
return false;
}
return true;
}
/**
* 检测上传文件大小
* @param $fileSize
* @param string $allowSize
* @return bool
*/
public function checkSize($fileSize, $allowSize = '')
{
$allowSize = str_replace(' ', '', $allowSize);
$allowUploadSizeConf = ConfServiceFacade::get('system.upload.size');
// 没有配置,也没有传入上传文件大小限制参数,即程序上不限制上传文件大小
if (!$allowUploadSizeConf && !$allowSize) {
return true;
}
$maxSize = $allowSize ? $allowSize : $allowUploadSizeConf;
preg_match('/(\d+)(\w+)/', $maxSize, $matches);
$type = strtolower($matches[2]);
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
$maxSize = (int)$maxSize * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
if ($fileSize > $maxSize) {
$this->setError('上传失败,文件大小超过 ' . $allowSize);
return false;
}
return true;
}
/**
* 检测上传文件后缀
* @param $fileName
* @param $fileExt
* @param string $allowExt
* @return bool
*/
public function checkExt($fileName, $fileExt, $allowExt = '')
{
$allowExtArr = explode(',', strtolower($allowExt));
//禁止上传PHP和HTML文件
if (in_array($fileExt, ['php', 'html', 'htm'])) {
$this->setError('上传失败,禁止上传php和html文件');
return false;
}
//验证文件后缀
$allowExtConf = ConfServiceFacade::get('system.upload.mime');
// 没有配置,也没有传入上传文件大小限制参数,即程序上不限制上传文件大小
if (!$allowExtConf && !$allowExt) {
$this->setError('上传失败,允许上传的文件后缀为空,请到系统配置 - 上传配置进行设置');
return false;
}
if ($allowExt !== '*' && (!in_array($fileExt, $allowExtArr))) {
$this->setError('上传失败,允许上传的文件后缀为' . $allowExt . ',实际上传文件[ ' . $fileName . ' ]的后缀为' . $fileExt);
return false;
}
return true;
}
/**
* 检测上传文件类型
* @param $fileMime
* @return bool
*/
public function checkMime($fileMime)
{
//禁止上传PHP和HTML文件
if (in_array($fileMime, ['text/x-php', 'text/html'])) {
$this->setError('上传失败,禁止上传php和html文件');
return false;
}
return true;
}
/**
* 编辑器内容,添加上传文件的域名前缀,一般提供给数据模型层getFiledAttr方法调用
* @param $string
* @param $uploadType
* @return string|string[]|null
*/
static public function addUploadDomain($string, $uploadType = 'local')
{
$defaultType = ConfServiceFacade::get('system.upload.defaultType', 'local');
if($uploadType == 'default') $uploadType = $defaultType;
$uploadDomain = self::getUploadDomain($uploadType, 'via');
//ueditor编辑器正则替换所有的图片、视频、音频
/* $string = preg_replace("/(<img .*?src=\")^(?!http)(.*?)(\".*?>+)/is", "\${1}{$uploadDomain}\${2}\${3}", $string);*/
preg_match_all("/(<img .*?src=\")(.*?)(\".*?>+)/is", $string, $matches);
if ($matches && isset($matches['2'])) {
foreach ($matches['2'] as $item) {
if (substr($item, 0, 4) != 'http') {
$string = str_replace($item, $uploadDomain . $item, $string);
}
}
}
$string = preg_replace("/(<video .*?src=\")(.*?)(\".*?>+)/is", "\${1}{$uploadDomain}\${2}\${3}", $string);
$string = preg_replace("/(<source .*?src=\")(.*?)(\".*?>+)/is", "\${1}{$uploadDomain}\${2}\${3}", $string);
//meditor编辑器正则替换所有的图片
$string = preg_replace("/(\!\[\]\()(.*?)(\))/is", "\${1}{$uploadDomain}\${2}\${3}", $string);
return $string;
}
/**
* 编辑器内容,删除上传文件的域名前缀,一般提供给控制器添加和编辑方法调用
* @param $string
* @param $uploadType
* @return string|string[]|null
*/
static public function delUploadDomain($string, $uploadType = 'local')
{
$defaultType = ConfServiceFacade::get('system.upload.defaultType', 'local');
if($uploadType == 'default') $uploadType = $defaultType;
$uploadDomain = addcslashes(self::getUploadDomain($uploadType, 'via'), '/');
//ueditor编辑器正则替换所有的图片、视频、音频
$string = preg_replace("/(<img .*?src=\"){$uploadDomain}(.*?)(\".*?>+)/is", "\${1}\${2}\${3}", $string);
$string = preg_replace("/(<video .*?src=\"){$uploadDomain}(.*?)(\".*?>+)/is", "\${1}\${2}\${3}", $string);
$string = preg_replace("/(<source .*?src=\"){$uploadDomain}(.*?)(\".*?>+)/is", "\${1}\${2}\${3}", $string);
//meditor编辑器正则替换所有的图片
$string = preg_replace("/(\!\[\]\(){$uploadDomain}(.*?)(\))/is", "\${1}\${2}\${3}", $string);
return $string;
}
/**
* 获取文件上传后访问的域名
* @param string $uploadType 上传方式
* @param string $viaServer 上传是否经过服务器
* @return mixed|string
*/
static public function getUploadDomain($uploadType = 'local', $viaServer = 'via')
{
$uploadDomain = '';
if ($uploadType === 'local') {
$uploadDomain = Env::get('domain.static', request()->domain() . '/static');
} else if ($uploadType === 'qiniu-kodo') {
$uploadDomain = ConfServiceFacade::get('plugin.qiniu_kodo.domain');
} else if ($uploadType === 'ali-oss') {
if ($viaServer === 'via') {
$uploadDomain = ConfServiceFacade::get('plugin.ali_oss.domain');
} else {
$uploadDomain = ConfServiceFacade::get('plugin.ali_oss_sts.domain');
}
}
return $uploadDomain;
}
// 设置上传方式为本地时的path,提供给当前类的singleAddUploadDomain方法调用
static public function setLocalPath($data)
{
$uploadDomain = self::getUploadDomain($data['upload_type']);
$uploadType = $data['upload_type'];
$value = $data['path'];
if($uploadType === 'local'){
if($uploadDomain){
$value = '/storage/' . $data['path'];
}else{
$value = '/static' . $value;
}
}
return $value;
}
/**
* 上传控件,单个,添加域名前缀,提供给Files模型层getPathAttr方法调用
* @param $data
* @return string
*/
static public function singleAddUploadDomain($data)
{
$uploadDomain = self::getUploadDomain($data['upload_type'], $data['via_server']);
$value = self::setLocalPath($data);
return $uploadDomain . '/' . ltrim($value, '/');
}
/**
* 上传控件,单个,保存path时,删除掉域名前缀,此方法仅FileController的add方法调用
* @param $data
* @return mixed
*/
static public function singleDelUploadDomain($data)
{
$uploadDomain = self::getUploadDomain($data['upload_type'], $data['via_server']);
return str_replace($uploadDomain, '', $data['path']);
}
/**
* 上传控件,多个,整理成前端需要的数据,以[, ]组合的字符串
* @param $fileIds
* @return array|boolean
*/
static public function multiJoin($fileIds)
{
try {
$files = Files::where('id', 'in', $fileIds)->select()->toArray();
$idArr = [];
$pathArr = [];
$filenameArr = [];
foreach ($files as $v) {
$idArr[] = $v['id'];
$pathArr[] = $v['path'];
$filenameArr[] = $v['name'];
}
return [
'id' => $fileIds,
'path' => join(', ', $pathArr),
'filename' => join(', ', $filenameArr)
];
} catch (\Exception $e) {
return false;
}
}
/**
* 获取默认的用户头像
* @return string
*/
public static function getDefaultAvatar()
{
$path = '/admin/images/avatar.jpg';
$uploadDomain = Env::get('domain.static', request()->domain() . '/static');
return $uploadDomain . $path;
}
}