Initial commit,修正

This commit is contained in:
2025-07-13 19:37:38 +08:00
parent 38ce288e27
commit 65bbd06981
12384 changed files with 3985464 additions and 8 deletions
+460
View File
@@ -0,0 +1,460 @@
<?php
/**
* UEditor Widget扩展
* @author xbzbing<xbzbing@gmail.com>
* @link www.crazydb.com
*
* UEditor版本v1.4.3.1
* Yii 版本 2.0+
*/
namespace crazydb\ueditor;
use yii;
use yii\imagine\Image;
use yii\web\Controller;
/**
* Class UEditorController
* 负责UEditor后台响应
* @package crazydb\ueditor
*/
class UEditorController extends Controller
{
/**
* UEditor的配置
* @see http://fex-team.github.io/ueditor/#start-config
* @var array
*/
public $config;
/**
* 列出文件/图片时需要忽略的文件夹
* 主要用于处理缩略图管理,兼容比如elFinder之类的程序
* @var array
*/
public $ignoreDir = [
'.thumbnails'
];
/**
* 缩略图设置
* 默认为200*200,如果设置为空数组则不生成缩略图
* @var array
*/
public $thumbnail = ['height' => 200, 'width' => 200];
/**
* 图片缩放设置
* 默认不缩放。
* 配置如 ['height'=>200,'width'=>200]
* @var array
*/
public $zoom = [];
/**
* 水印设置
* 参考配置如下:
* ['path'=>'水印图片位置','start'=>[0, 0]]
* 默认位置为[0, 0],可不配置
* @var array
*/
public $watermark = [];
/**
* 默认 action
* @var string
*/
public $defaultAction = 'index';
/**
* Web根目录
* @var string
*/
protected $webroot;
public function init()
{
parent::init();
//CSRF 基于 POST 验证,UEditor 无法添加自定义 POST 数据,同时由于这里不会产生安全问题,故简单粗暴地取消 CSRF 验证。
//如需 CSRF 防御,可以使用 server_param 方法,然后在这里将 Get 的 CSRF 添加到 POST 的数组中。。。
Yii::$app->request->enableCsrfValidation = false;
//当客户使用低版本IE时,会使用swf上传插件,维持认证状态可以参考文档UEditor「自定义请求参数」部分。
//http://fex.baidu.com/ueditor/#server-server_param
//保留UE默认的配置引入方式
if (file_exists(__DIR__ . '/config.json'))
$CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", '', file_get_contents(__DIR__ . '/config.json')), true);
else
$CONFIG = [];
if (!is_array($this->config))
$this->config = [];
if (!is_array($CONFIG))
$CONFIG = [];
$default = [
'imagePathFormat' => '/upload/image/{yyyy}{mm}{dd}/{time}{rand:8}',
'scrawlPathFormat' => '/upload/image/{yyyy}{mm}{dd}/{time}{rand:8}',
'snapscreenPathFormat' => '/upload/image/{yyyy}{mm}{dd}/{time}{rand:8}',
'catcherPathFormat' => '/upload/image/{yyyy}{mm}{dd}/{time}{rand:8}',
'videoPathFormat' => '/upload/video/{yyyy}{mm}{dd}/{time}{rand:8}',
'filePathFormat' => '/upload/file/{yyyy}{mm}{dd}/{rand:8}_{filename}',
'imageManagerListPath' => '/upload/image/',
'fileManagerListPath' => '/upload/file/',
];
$this->config = $this->config + $default + $CONFIG;
$this->webroot = Yii::getAlias('@webroot');
if(!is_array($this->thumbnail))
$this->thumbnail = false;
}
/**
* 蛋疼的统一后台入口
*/
public function actionIndex()
{
$action = strtolower(Yii::$app->request->get('action', 'config'));
$actions = [
'uploadimage' => 'upload-image',
'uploadscrawl' => 'upload-scrawl',
'uploadvideo' => 'upload-video',
'uploadfile' => 'upload-file',
'listimage' => 'list-image',
'listfile' => 'list-file',
'catchimage' => 'catch-image',
'config' => 'config',
'listinfo' => 'list-info'
];
if (isset($actions[$action]))
return $this->run($actions[$action]);
else
return $this->show(['state' => 'Unknown action.']);
}
/**
* 显示配置信息
*/
public function actionConfig()
{
return $this->show($this->config);
}
/**
* 上传图片
*/
public function actionUploadImage()
{
$config = [
'pathFormat' => $this->config['imagePathFormat'],
'maxSize' => $this->config['imageMaxSize'],
'allowFiles' => $this->config['imageAllowFiles']
];
$fieldName = $this->config['imageFieldName'];
$result = $this->upload($fieldName, $config);
return $this->show($result);
}
/**
* 上传涂鸦
*/
public function actionUploadScrawl()
{
$config = [
'pathFormat' => $this->config['scrawlPathFormat'],
'maxSize' => $this->config['scrawlMaxSize'],
'allowFiles' => $this->config['scrawlAllowFiles'],
'oriName' => 'scrawl.png'
];
$fieldName = $this->config['scrawlFieldName'];
$result = $this->upload($fieldName, $config, 'base64');
return $this->show($result);
}
/**
* 上传视频
*/
public function actionUploadVideo()
{
$config = [
'pathFormat' => $this->config['videoPathFormat'],
'maxSize' => $this->config['videoMaxSize'],
'allowFiles' => $this->config['videoAllowFiles']
];
$fieldName = $this->config['videoFieldName'];
$result = $this->upload($fieldName, $config);
return $this->show($result);
}
/**
* 上传文件
*/
public function actionUploadFile()
{
$config = [
'pathFormat' => $this->config['filePathFormat'],
'maxSize' => $this->config['fileMaxSize'],
'allowFiles' => $this->config['fileAllowFiles']
];
$fieldName = $this->config['fileFieldName'];
$result = $this->upload($fieldName, $config);
return $this->show($result);
}
/**
* 文件列表
*/
public function actionListFile()
{
$allowFiles = $this->config['fileManagerAllowFiles'];
$listSize = $this->config['fileManagerListSize'];
$path = $this->config['fileManagerListPath'];
$result = $this->manage($allowFiles, $listSize, $path);
return $this->show($result);
}
/**
* 图片列表
*/
public function actionListImage()
{
$allowFiles = $this->config['imageManagerAllowFiles'];
$listSize = $this->config['imageManagerListSize'];
$path = $this->config['imageManagerListPath'];
$result = $this->manage($allowFiles, $listSize, $path);
return $this->show($result);
}
/**
* 获取远程图片
*/
public function actionCatchImage()
{
/* 上传配置 */
$config = [
'pathFormat' => $this->config['catcherPathFormat'],
'maxSize' => $this->config['catcherMaxSize'],
'allowFiles' => $this->config['catcherAllowFiles'],
'oriName' => 'remote.png'
];
$fieldName = $this->config['catcherFieldName'];
/* 抓取远程图片 */
$list = [];
if (isset($_POST[$fieldName])) {
$source = $_POST[$fieldName];
} else {
$source = $_GET[$fieldName];
}
foreach ($source as $imgUrl) {
$item = new Uploader($imgUrl, $config, 'remote');
$info = $item->getFileInfo();
$info['thumbnail'] = $this->imageHandle($info['url']);
$list[] = [
'state' => $info['state'],
'url' => $info['url'],
'source' => $imgUrl
];
}
/* 返回抓取数据 */
return [
'state' => count($list) ? 'SUCCESS' : 'ERROR',
'list' => $list
];
}
/**
* 各种上传
* @param $fieldName
* @param $config
* @param $base64
* @return array
*/
protected function upload($fieldName, $config, $base64 = 'upload')
{
$up = new Uploader($fieldName, $config, $base64);
$info = $up->getFileInfo();
if ($this->thumbnail && $info['state'] == 'SUCCESS' && in_array($info['type'], ['.png', '.jpg', '.bmp', '.gif'])) {
$info['thumbnail'] = Yii::$app->request->baseUrl . $this->imageHandle($info['url']);
}
$info['url'] = Yii::$app->request->baseUrl . $info['url'];
$info['original'] = htmlspecialchars($info['original']);
$info['width'] = $info['height'] = 500;
return $info;
}
/**
* 自动处理图片
* @param $fullName
* @return mixed|string
*/
protected function imageHandle($fullName)
{
if (substr($fullName, 0, 1) != '/')
$fullName = '/' . $fullName;
$file = $fullName;
//先处理缩略图
if ($this->thumbnail && !empty($this->thumbnail['height']) && !empty($this->thumbnail['width'])) {
$file = pathinfo($file);
$file = $file['dirname'] . '/' . $file['filename'] . '_thumbnail.' . $file['extension'];
Image::thumbnail($this->webroot . $fullName, intval($this->thumbnail['width']), intval($this->thumbnail['height']))
->save($this->webroot . $file);
}
//再处理缩放,默认不缩放
//...缩放效果非常差劲-,-
if (isset($this->zoom['height']) && isset($this->zoom['width'])) {
$size = $this->getSize($this->webroot . $fullName);
if ($size && $size[0] > 0 && $size[1] > 0) {
$ratio = min([$this->zoom['height'] / $size[0], $this->zoom['width'] / $size[1], 1]);
Image::thumbnail($this->webroot . $fullName, ceil($size[0] * $ratio), ceil($size[1] * $ratio))
->save($this->webroot . $fullName);
}
}
//最后生成水印
if (isset($this->watermark['path']) && file_exists($this->watermark['path'])) {
if (!isset($this->watermark['start']))
$this->watermark['start'] = [0, 0];
Image::watermark($file, $this->watermark['path'], $this->watermark['start'])
->save($file);
}
return $file;
}
/**
* 获取图片的大小
* 主要用于获取图片大小并
* @param $file
* @return array
*/
protected function getSize($file)
{
if (!file_exists($file))
return [];
$info = pathinfo($file);
$image = null;
switch (strtolower($info['extension'])) {
case 'gif':
$image = imagecreatefromgif($file);
break;
case 'jpg':
case 'jpeg':
$image = imagecreatefromjpeg($file);
break;
case 'png':
$image = imagecreatefrompng($file);
break;
default:
break;
}
if ($image == null)
return [];
else
return [imagesx($image), imagesy($image)];
}
/**
* 文件和图片管理action使用
* @param $allowFiles
* @param $listSize
* @param $path
* @return array
*/
protected function manage($allowFiles, $listSize, $path)
{
$allowFiles = substr(str_replace('.', '|', join('', $allowFiles)), 1);
/* 获取参数 */
$size = isset($_GET['size']) ? $_GET['size'] : $listSize;
$start = isset($_GET['start']) ? $_GET['start'] : 0;
$end = $start + $size;
/* 获取文件列表 */
$path = $this->webroot . (substr($path, 0, 1) == '/' ? '' : '/') . $path;
$files = $this->getFiles($path, $allowFiles);
if (!count($files)) {
$result = [
'state' => 'no match file',
'list' => [],
'start' => $start,
'total' => count($files),
];
return $result;
}
/* 获取指定范围的列表 */
$len = count($files);
for ($i = min($end, $len) - 1, $list = []; $i < $len && $i >= 0 && $i >= $start; $i--) {
$list[] = $files[$i];
}
/* 返回数据 */
$result = [
'state' => 'SUCCESS',
'list' => $list,
'start' => $start,
'total' => count($files),
];
return $result;
}
/**
* 遍历获取目录下的指定类型的文件
* @param $path
* @param $allowFiles
* @param array $files
* @return array|null
*/
protected function getFiles($path, $allowFiles, &$files = [])
{
if (!is_dir($path)) return null;
if (in_array(basename($path), $this->ignoreDir)) return null;
if (substr($path, strlen($path) - 1) != '/') $path .= '/';
$handle = opendir($path);
//baseUrl用于兼容使用alias的二级目录部署方式
$baseUrl = Yii::$app->request->baseUrl;
while (false !== ($file = readdir($handle))) {
if ($file != '.' && $file != '..') {
$path2 = $path . $file;
if (is_dir($path2)) {
$this->getFiles($path2, $allowFiles, $files);
} else {
if ($this->action->id == 'list-image' && $this->thumbnail) {
$pat = "/\_thumbnail\.(" . $allowFiles . ")$/i";
} else {
$pat = "/\.(" . $allowFiles . ")$/i";
}
if (preg_match($pat, $file)) {
$files[] = [
'url' => $baseUrl . substr($path2, strlen($this->webroot)),
'mtime' => filemtime($path2)
];
}
}
}
}
return $files;
}
/**
* 最终显示结果,自动输出 JSONP 或者 JSON
* @param array $result
* @return array
*/
protected function show($result)
{
$callback = Yii::$app->request->get('callback', null);
if ($callback && is_string($callback)) {
Yii::$app->response->format = yii\web\Response::FORMAT_JSONP;
return [
'callback' => $callback,
'data' => $result
];
}
Yii::$app->response->format = yii\web\Response::FORMAT_JSON;
return $result;
}
}