init
This commit is contained in:
468
app/admin/controller/Ueditor.php
Executable file
468
app/admin/controller/Ueditor.php
Executable file
@@ -0,0 +1,468 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\Lang;
|
||||
use think\Loader;
|
||||
use think\Config;
|
||||
use image\Image;
|
||||
|
||||
class Ueditor extends BaseController {
|
||||
|
||||
private $basePath = '/';
|
||||
private $saveDirectory = 'default';
|
||||
private $config; //配置信息
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
date_default_timezone_set("Asia/Shanghai");
|
||||
$this->docDir = $this->request->server('DOCUMENT_ROOT');
|
||||
$this->rootDir = $this->request->root();
|
||||
$this->basePath = $this->docDir . $this->rootDir . '/uploads';
|
||||
$this->saveDirectory = 'temp';
|
||||
error_reporting(E_ERROR | E_WARNING);
|
||||
Config::set('url_common_param', true);
|
||||
header("Content-Type: text/html; charset=utf-8");
|
||||
}
|
||||
|
||||
//上传文件
|
||||
private function upFile($fileField, $config = array()) {
|
||||
$result = array('state' => "ERROR_UNKNOWN 未知错误");
|
||||
$file = $this->request->file($fileField);
|
||||
if (empty($file)) {
|
||||
$file = $this->request->file('upfile');
|
||||
}
|
||||
// $error = $this->validate(
|
||||
// ['file' => $file], ['file' => 'image|fileSize:40000000|fileExt:jpg,jpeg,gif,png'], ['file.image' => '上传文件必须为图片', 'file.fileSize' => '上传文件过大', 'file.fileExt' => '上传文件后缀名必须为jpg,jpeg,gif,png']
|
||||
// );
|
||||
$error = true;
|
||||
if (true !== $error || empty($file)) {
|
||||
return json_encode(['state' => "ERROR " . $error]);
|
||||
} else {
|
||||
// 移动到框架应用根目录/public/uploads/ 目录下
|
||||
$saveDirectory = $this->saveDirectory . '/' . date('Y/md') . '/';
|
||||
// 使用自定义的文件保存规则
|
||||
$info = $file->rule(function($file) {
|
||||
return md5(mt_rand());
|
||||
})->move($this->basePath . '/' . $saveDirectory);
|
||||
if ($info) {
|
||||
$result = array(
|
||||
'state' => 'SUCCESS',
|
||||
'url' => '/uploads/' . $saveDirectory . $info->getFilename(),
|
||||
'title' => $info->getFilename(),
|
||||
'original' => $info->getFilename(),
|
||||
'type' => '.' . $info->getExtension(),
|
||||
'size' => $info->getSize(),
|
||||
);
|
||||
//图片加水印
|
||||
$ext = strtolower($info->getExtension());
|
||||
if (in_array($ext, ['gif', 'jpg', 'jpeg', 'png', 'bmp'])) {
|
||||
$this->watermark('/uploads/' . $saveDirectory . $info->getFilename());
|
||||
}
|
||||
} else {
|
||||
$result['state'] = 'ERROR ' . $file->getError();
|
||||
}
|
||||
}
|
||||
return json_encode($result);
|
||||
}
|
||||
|
||||
/*
|
||||
* 处理base64编码的图片上传
|
||||
* 例如:涂鸦图片上传
|
||||
*/
|
||||
|
||||
private function upBase64($fileField, $config) {
|
||||
$base64Data = $this->request->post($fileField);
|
||||
$img = base64_decode($base64Data);
|
||||
$dirname = $this->basePath . '/' . $this->saveDirectory . '/';
|
||||
$file['filesize'] = strlen($img);
|
||||
$file['oriName'] = $config['oriName'];
|
||||
$file['ext'] = strtolower(strrchr($config['oriName'], '.'));
|
||||
$file['name'] = uniqid() . $file['ext'];
|
||||
$file['fullName'] = $dirname . $file['name'];
|
||||
$fullName = $file['fullName'];
|
||||
//检查文件大小是否超出限制
|
||||
if ($file['filesize'] >= ($config["maxSize"])) {
|
||||
$data = array(
|
||||
'state' => '文件大小超出网站限制',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//创建目录失败
|
||||
if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
|
||||
$data = array(
|
||||
'state' => '目录创建失败',
|
||||
);
|
||||
return json_encode($data);
|
||||
} else if (!is_writeable($dirname)) {
|
||||
$data = array(
|
||||
'state' => '目录没有写权限',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//移动文件
|
||||
if (!(file_put_contents($fullName, $img) && file_exists($fullName))) { //移动失败
|
||||
$data = array(
|
||||
'state' => '写入文件内容错误',
|
||||
);
|
||||
} else { //移动成功
|
||||
$data = array(
|
||||
'state' => 'SUCCESS',
|
||||
'url' => substr($file['fullName'], 1),
|
||||
'title' => $file['name'],
|
||||
'original' => $file['oriName'],
|
||||
'type' => $file['ext'],
|
||||
'size' => $file['filesize'],
|
||||
);
|
||||
}
|
||||
return json_encode($data);
|
||||
}
|
||||
|
||||
//列出图片
|
||||
private function listFile($allowFiles, $listSize, $get) {
|
||||
$dirname = $this->basePath . '/' . $this->saveDirectory . '/';
|
||||
$allowFiles = substr(str_replace(".", "|", join("", $allowFiles)), 1);
|
||||
/* 获取参数 */
|
||||
$size = isset($get['size']) ? htmlspecialchars($get['size']) : $listSize;
|
||||
$start = isset($get['start']) ? htmlspecialchars($get['start']) : 0;
|
||||
$end = $start + $size;
|
||||
/* 获取文件列表 */
|
||||
$path = $dirname;
|
||||
$files = $this->getFiles($path, $allowFiles);
|
||||
if (!count($files)) {
|
||||
return json_encode(array(
|
||||
"state" => "no match file",
|
||||
"list" => array(),
|
||||
"start" => $start,
|
||||
"total" => count($files)
|
||||
));
|
||||
}
|
||||
/* 获取指定范围的列表 */
|
||||
$len = count($files);
|
||||
for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--) {
|
||||
$list[] = $files[$i];
|
||||
}
|
||||
// /* 倒序 */
|
||||
// for ($i = $end, $list = array(); $i < $len && $i < $end; $i++) {
|
||||
// $list[] = $files[$i];
|
||||
// }
|
||||
/* 返回数据 */
|
||||
$result = json_encode(array(
|
||||
"state" => "SUCCESS",
|
||||
"list" => $list,
|
||||
"start" => $start,
|
||||
"total" => count($files)
|
||||
));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* 遍历获取目录下的指定类型的文件
|
||||
* @param $path
|
||||
* @param array $files
|
||||
* @return array
|
||||
*/
|
||||
|
||||
private function getFiles($path, $allowFiles, &$files = array()) {
|
||||
if (!is_dir($path))
|
||||
return null;
|
||||
if (substr($path, strlen($path) - 1) != '/')
|
||||
$path .= '/';
|
||||
$handle = opendir($path);
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if ($file != '.' && $file != '..') {
|
||||
$path2 = $path . $file;
|
||||
if (is_dir($path2)) {
|
||||
$this->getFiles($path2, $allowFiles, $files);
|
||||
} else {
|
||||
if (preg_match("/\.(" . $allowFiles . ")$/i", $file)) {
|
||||
$files[] = array(
|
||||
'url' => substr($path2, strlen($_SERVER['DOCUMENT_ROOT'])),
|
||||
'mtime' => filemtime($path2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取远程图片
|
||||
* @return mixed
|
||||
*/
|
||||
private function saveRemotess($fieldName, $config) {
|
||||
$imgUrl = htmlspecialchars($fieldName);
|
||||
$imgUrl = str_replace("&", "&", $imgUrl);
|
||||
//http开头验证
|
||||
if (strpos($imgUrl, "http") !== 0) {
|
||||
$data = array(
|
||||
'state' => '链接不是http链接',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//获取请求头并检测死链
|
||||
$heads = get_headers($imgUrl);
|
||||
if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
|
||||
$data = array(
|
||||
'state' => '链接不可用',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//格式验证(扩展名验证和Content-Type验证)
|
||||
$fileType = strtolower(strrchr($imgUrl, '.'));
|
||||
if (!in_array($fileType, $config['allowFiles']) || stristr($heads['Content-Type'], "image")) {
|
||||
$data = array(
|
||||
'state' => '链接contentType不正确',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//打开输出缓冲区并获取远程图片
|
||||
ob_start();
|
||||
$context = stream_context_create(
|
||||
array('http' => array(
|
||||
'follow_location' => false // don't follow redirects
|
||||
))
|
||||
);
|
||||
readfile($imgUrl, false, $context);
|
||||
$img = ob_get_contents();
|
||||
ob_end_clean();
|
||||
preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);
|
||||
$dirname = $this->basePath . '/' . $this->saveDirectory . '/' . date('Y/md') . '/';
|
||||
$file['oriName'] = $m ? $m[1] : "";
|
||||
$file['filesize'] = strlen($img);
|
||||
$file['ext'] = strtolower(strrchr($config['oriName'], '.'));
|
||||
$file['name'] = md5(mt_rand()) . $file['ext'];
|
||||
$file['fullName'] = $dirname . $file['name'];
|
||||
$fullName = $file['fullName'];
|
||||
//检查文件大小是否超出限制
|
||||
if ($file['filesize'] >= ($config["maxSize"])) {
|
||||
$data = array(
|
||||
'state' => '文件大小超出网站限制',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//创建目录失败
|
||||
if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
|
||||
$data = array(
|
||||
'state' => '目录创建失败',
|
||||
);
|
||||
return json_encode($data);
|
||||
} else if (!is_writeable($dirname)) {
|
||||
$data = array(
|
||||
'state' => '目录没有写权限',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//移动文件
|
||||
if (!(file_put_contents($fullName, $img) && file_exists($fullName))) { //移动失败
|
||||
$data = array(
|
||||
'state' => '写入文件内容错误',
|
||||
);
|
||||
return json_encode($data);
|
||||
} else { //移动成功
|
||||
$data = array(
|
||||
'state' => 'SUCCESS',
|
||||
'url' => substr($file['fullName'], strlen($this->docDir . $this->rootDir)),
|
||||
'title' => $file['name'],
|
||||
'original' => $file['oriName'],
|
||||
'type' => $file['ext'],
|
||||
'size' => $file['filesize'],
|
||||
);
|
||||
}
|
||||
|
||||
return json_encode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取远程图片
|
||||
* @return mixed
|
||||
*/
|
||||
private function saveRemote($fileField, $config = array()) {
|
||||
$imgUrl = htmlspecialchars($fileField);
|
||||
$imgUrl = str_replace("&", "&", $imgUrl);
|
||||
//http开头验证
|
||||
if (strpos($imgUrl, "http") !== 0) {
|
||||
$data = array(
|
||||
'state' => '链接不是http链接',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
preg_match('/(^https*:\/\/[^:\/]+)/', $imgUrl, $matches);
|
||||
$host_with_protocol = count($matches) > 1 ? $matches[1] : '';
|
||||
// 判断是否是合法 url
|
||||
if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
|
||||
$data = array(
|
||||
'state' => 'INVALID_URL',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
preg_match('/^https*:\/\/(.+)/', $host_with_protocol, $matches);
|
||||
$host_without_protocol = count($matches) > 1 ? $matches[1] : '';
|
||||
// 此时提取出来的可能是 ip 也有可能是域名,先获取 ip
|
||||
$ip = gethostbyname($host_without_protocol);
|
||||
// 判断是否是私有 ip
|
||||
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
|
||||
$data = array(
|
||||
'state' => 'INVALID_IP',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//获取请求头并检测死链
|
||||
$heads = get_headers($imgUrl);
|
||||
if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
|
||||
$data = array(
|
||||
'state' => '链接不可用',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//格式验证(扩展名验证和Content-Type验证)
|
||||
$fileType = strtolower(strrchr($imgUrl, '.'));
|
||||
if (!in_array($fileType, $config['allowFiles']) || stristr($heads['Content-Type'], "image")) {
|
||||
$data = array(
|
||||
'state' => '链接contentType不正确',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//打开输出缓冲区并获取远程图片
|
||||
ob_start();
|
||||
$context = stream_context_create(array('http' => array(
|
||||
'follow_location' => false // don't follow redirects
|
||||
))
|
||||
);
|
||||
readfile($imgUrl, false, $context);
|
||||
$img = ob_get_contents();
|
||||
ob_end_clean();
|
||||
preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);
|
||||
$dirname = $this->basePath . '/' . $this->saveDirectory . '/' . date('Y/md') . '/';
|
||||
$file['oriName'] = $m ? $m[1] : "";
|
||||
$file['filesize'] = strlen($img);
|
||||
$file['ext'] = strtolower(strrchr($config['oriName'], '.'));
|
||||
$file['name'] = md5(mt_rand()) . $file['ext'];
|
||||
$file['fullName'] = $dirname . $file['name'];
|
||||
$fullName = $file['fullName'];
|
||||
//检查文件大小是否超出限制
|
||||
if ($file['filesize'] >= ($config["maxSize"])) {
|
||||
$data = array(
|
||||
'state' => '文件大小超出网站限制',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//创建目录失败
|
||||
if (!is_dir($dirname) && !mkdir($dirname, 0777, true)) {
|
||||
$data = array(
|
||||
'state' => '目录创建失败',
|
||||
);
|
||||
return json_encode($data);
|
||||
} else if (!is_writeable($dirname)) {
|
||||
$data = array(
|
||||
'state' => '目录没有写权限',
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
//移动文件
|
||||
if (!(file_put_contents($fullName, $img) && is_file($fullName))) { //移动失败
|
||||
$data = array(
|
||||
'state' => '写入文件内容错误',
|
||||
);
|
||||
return json_encode($data);
|
||||
} else { //移动成功
|
||||
//$this->watermark(substr($file['fullName'], strlen($this->docDir . $this->rootDir)));
|
||||
$data = array(
|
||||
'state' => 'SUCCESS',
|
||||
'url' => substr($file['fullName'], strlen($this->docDir . $this->rootDir)),
|
||||
'title' => $file['name'],
|
||||
'original' => $file['oriName'],
|
||||
'type' => $file['ext'],
|
||||
'size' => $file['filesize'],
|
||||
);
|
||||
}
|
||||
|
||||
return json_encode($data);
|
||||
}
|
||||
|
||||
public function watermark($return_url = '/uploads/nopic.jpg') {
|
||||
$iswatermark = Config::get('watermark');
|
||||
$return_data = ['watermark' => $iswatermark];
|
||||
if ($iswatermark) {
|
||||
$wmconfig = [
|
||||
'watermark' => $iswatermark,
|
||||
'mark_type' => Config::get('mark_type'),
|
||||
'mark_image' => Config::get('mark_image'),
|
||||
'mark_width_height' => Config::get('mark_width_height'),
|
||||
'mark_text' => Config::get('mark_text'),
|
||||
'mark_text_color' => Config::get('mark_text_color'),
|
||||
'mark_degree' => Config::get('mark_degree'),
|
||||
'mark_quality' => Config::get('mark_quality'),
|
||||
'mark_position' => Config::get('mark_position'),
|
||||
];
|
||||
$imgresource = '.' . $return_url;
|
||||
$image = Image::open($imgresource);
|
||||
//$image->open($imgresource);
|
||||
$return_data['mark_type'] = $wmconfig['mark_type'];
|
||||
if ($image->width() > $wmconfig['mark_width_height']['width'] && $image->height() > $wmconfig['mark_width_height']['height']) {
|
||||
$save_filename = $this->basePath . '/original_image' . substr($return_url, 8); //截取 /uploads 后的内容
|
||||
if (!is_dir(dirname($save_filename))) {
|
||||
mkdir(dirname($save_filename), 0777, true);
|
||||
}
|
||||
$image->save($save_filename, null, 100);
|
||||
if ($wmconfig['mark_type'] == 'text') {
|
||||
//$image->text($wmconfig['mark_text'],'./hgzb.ttf',20,'#000000',9)->save($imgresource);
|
||||
$ttf = './hgzb.ttf';
|
||||
if (file_exists($ttf)) {
|
||||
$size = $wmconfig['mark_text_size'] ? $wmconfig['mark_text_size'] : 30;
|
||||
$color = $wmconfig['mark_text_color'] ? : '#000000';
|
||||
if (!preg_match('/^#[0-9a-fA-F]{6}$/', $color)) {
|
||||
$color = '#000000';
|
||||
}
|
||||
$transparency = intval((100 - $wmconfig['mark_degree']) * (127 / 100));
|
||||
$color .= dechex($transparency);
|
||||
$image->open($imgresource)->text($wmconfig['mark_text'], $ttf, $size, $color, $wmconfig['mark_position'])->save($imgresource);
|
||||
$return_data['mark_text'] = $wmconfig['mark_text'];
|
||||
}
|
||||
} else {
|
||||
//$image->water('.'.$wmconfig['mark_img'],9,$wmconfig['mark_degree'])->save($imgresource);
|
||||
$waterPath = '.' . $wmconfig['mark_image'];
|
||||
$quality = $wmconfig['mark_quality'] ? $wmconfig['mark_quality'] : 80;
|
||||
$waterTempPath = dirname($waterPath) . '/temp_' . basename($waterPath);
|
||||
$image->open($waterPath)->save($waterTempPath, null, $quality);
|
||||
$image->open($imgresource)->water($waterTempPath, $wmconfig['mark_position'], $wmconfig['mark_degree'])->save($imgresource);
|
||||
@unlink($waterTempPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 规则替换命名文件
|
||||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
private function getFullPath($path) {
|
||||
//替换日期事件
|
||||
$t = time();
|
||||
$d = explode('-', date("Y-y-m-d-H-i-s"));
|
||||
$format = $path;
|
||||
$format = str_replace("{yyyy}", $d[0], $format);
|
||||
$format = str_replace("{yy}", $d[1], $format);
|
||||
$format = str_replace("{mm}", $d[2], $format);
|
||||
$format = str_replace("{dd}", $d[3], $format);
|
||||
$format = str_replace("{hh}", $d[4], $format);
|
||||
$format = str_replace("{ii}", $d[5], $format);
|
||||
$format = str_replace("{ss}", $d[6], $format);
|
||||
$format = str_replace("{uid}", $this->user_id, $format);
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
private function format_exts($exts) {
|
||||
$data = array();
|
||||
foreach ($exts as $key => $value) {
|
||||
$data[] = ltrim($value, '.');
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user