Ueditor.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 山西牛酷信息科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com.cn
  8. * 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用。
  9. * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
  10. * =========================================================
  11. */
  12. namespace app\admin\controller;
  13. use app\Controller;
  14. use app\model\upload\Upload as UploadModel;
  15. /**
  16. * 百度编辑器上传
  17. */
  18. class Ueditor extends Controller {
  19. public function index(){
  20. date_default_timezone_set("Asia/chongqing");
  21. error_reporting(E_ERROR);
  22. header("Content-Type: text/html; charset=utf-8");
  23. $CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents("./public/static/ext/ueditor/php/config.json")), true);
  24. $action = $_GET['action'];
  25. switch ($action) {
  26. case 'config':
  27. $result = json_encode($CONFIG);
  28. break;
  29. /* 上传图片 */
  30. case 'uploadimage':
  31. $fieldName = $CONFIG['imageFieldName'];
  32. $result = $this->upImage($fieldName);
  33. break;
  34. /* 上传涂鸦 */
  35. case 'uploadscrawl':
  36. $config = array(
  37. "pathFormat" => $CONFIG['scrawlPathFormat'],
  38. "maxSize" => $CONFIG['scrawlMaxSize'],
  39. "allowFiles" => $CONFIG['scrawlAllowFiles'],
  40. "oriName" => "scrawl.png"
  41. );
  42. $fieldName = $CONFIG['scrawlFieldName'];
  43. $base64 = "base64";
  44. $result = $this->upBase64($config,$fieldName);
  45. break;
  46. /* 上传视频 */
  47. case 'uploadvideo':
  48. $fieldName = $CONFIG['videoFieldName'];
  49. $result = $this->upVideo($fieldName, $CONFIG['videoMaxSize']);
  50. break;
  51. /* 上传文件 */
  52. case 'uploadfile':
  53. $fieldName = $CONFIG['fileFieldName'];
  54. $result = $this->upFile($fieldName);
  55. break;
  56. /* 列出图片 */
  57. case 'listimage':
  58. $allowFiles = $CONFIG['imageManagerAllowFiles'];
  59. $listSize = $CONFIG['imageManagerListSize'];
  60. $path = $CONFIG['imageManagerListPath'];
  61. $get =$_GET;
  62. $result =$this->fileList($allowFiles,$listSize,$get);
  63. break;
  64. /* 列出文件 */
  65. case 'listfile':
  66. $allowFiles = $CONFIG['fileManagerAllowFiles'];
  67. $listSize = $CONFIG['fileManagerListSize'];
  68. $path = $CONFIG['fileManagerListPath'];
  69. $get = $_GET;
  70. $result = $this->fileList($allowFiles,$listSize,$get);
  71. break;
  72. /* 抓取远程文件 */
  73. case 'catchimage':
  74. $config = array(
  75. "pathFormat" => $CONFIG['catcherPathFormat'],
  76. "maxSize" => $CONFIG['catcherMaxSize'],
  77. "allowFiles" => $CONFIG['catcherAllowFiles'],
  78. "oriName" => "remote.png"
  79. );
  80. $fieldName = $CONFIG['catcherFieldName'];
  81. /* 抓取远程图片 */
  82. $list = array();
  83. isset($_POST[$fieldName]) ? $source = $_POST[$fieldName] : $source = $_GET[$fieldName];
  84. foreach($source as $imgUrl){
  85. $info = json_decode($this->saveRemote($config,$imgUrl),true);
  86. array_push($list, array(
  87. "state" => $info["state"],
  88. "url" => $info["url"],
  89. "size" => $info["size"],
  90. "title" => htmlspecialchars($info["title"]),
  91. "original" => htmlspecialchars($info["original"]),
  92. "source" => htmlspecialchars($imgUrl)
  93. ));
  94. }
  95. $result = json_encode(array(
  96. 'state' => count($list) ? 'SUCCESS':'ERROR',
  97. 'list' => $list
  98. ));
  99. break;
  100. default:
  101. $result = json_encode(array(
  102. 'state' => '请求地址出错'
  103. ));
  104. break;
  105. }
  106. /* 输出结果 */
  107. if(isset($_GET["callback"])){
  108. if(preg_match("/^[\w_]+$/", $_GET["callback"])){
  109. echo htmlspecialchars($_GET["callback"]).'('.$result.')';
  110. }else{
  111. echo json_encode(array(
  112. 'state' => 'callback参数不合法'
  113. ));
  114. }
  115. }else{
  116. echo $result;
  117. }
  118. }
  119. /**
  120. * 上传文件
  121. * @param unknown $fieldName
  122. */
  123. private function upFile($fieldName){
  124. $upload_service = new Upload();
  125. $upload_path = 'ueditor/file/'.date('Ymd');
  126. if(!empty($_FILES[$fieldName])){//上传成功
  127. $info = $upload_service->file($_FILES[$fieldName], $upload_path);
  128. if($info['code'] > 0){
  129. $data=array(
  130. 'state' => 'SUCCESS',
  131. 'url' => $info['data']['path'],
  132. 'title' => $info['data']['file_name'],
  133. 'original' => $info['data']['file_name'],
  134. 'type' => '.' . $info['data']['file_ext'],
  135. 'size' => $info['data']['size']
  136. );
  137. }else{
  138. $data = array(
  139. 'state' => $info['message']
  140. );
  141. }
  142. }else{
  143. $data = array(
  144. 'state' => '上传文件为空',
  145. );
  146. }
  147. return json_encode($data);
  148. }
  149. /**
  150. * 上传图片
  151. * @param unknown $fieldName
  152. * @return string
  153. */
  154. private function upImage($fieldName){
  155. $upload_service = new UploadModel();
  156. $upload_path = 'ueditor/image/'.date('Ymd');
  157. if(!empty($_FILES[$fieldName])){//上传成功
  158. $info = $upload_service->setPath("common/images/".date("Ymd"). '/')->image([
  159. 'name' => $fieldName,
  160. 'thumb_type' => ''
  161. ]);
  162. if($info['code'] >= 0){
  163. $data=array(
  164. 'state' => 'SUCCESS',
  165. 'url' => $info['data']['pic_path'],
  166. 'title' => $info['data']['pic_name'],
  167. 'original' => $info['data']['pic_name'],
  168. 'type' => '.' . $info['data']['file_ext'],
  169. );
  170. }else{
  171. $data = array(
  172. 'state' => $info['message']
  173. );
  174. }
  175. }else{
  176. $data = array(
  177. 'state' => '上传文件为空',
  178. );
  179. }
  180. return json_encode($data);
  181. }
  182. /**
  183. * 上传视频
  184. * @param unknown $fieldName
  185. */
  186. private function upVideo($fieldName, $size){
  187. $upload_service = new Upload();
  188. $upload_path = 'ueditor/video/'.date('Ymd');
  189. if(!empty($_FILES[$fieldName])){//上传成功
  190. $info = $upload_service->video($_FILES[$fieldName], $upload_path, $size);
  191. if($info['code'] > 0){
  192. $data=array(
  193. 'state' => 'SUCCESS',
  194. 'url' => $info['data']['path'],
  195. 'title' => $info['data']['file_name'],
  196. 'original' => $info['data']['file_name'],
  197. 'type' => '.' . $info['data']['file_ext'],
  198. 'size' => $info['data']['size']
  199. );
  200. }else{
  201. $data = array(
  202. 'state' => $info['message']
  203. );
  204. }
  205. }else{
  206. $data = array(
  207. 'state' => '上传文件为空',
  208. );
  209. }
  210. return json_encode($data);
  211. }
  212. //列出图片
  213. private function fileList($allowFiles,$listSize,$get){
  214. $dirname = UPLOAD . '/ueditor/';
  215. $allowFiles = substr(str_replace(".","|",join("",$allowFiles)),1);
  216. /* 获取参数 */
  217. $size = isset($get['size']) ? htmlspecialchars($get['size']) : $listSize;
  218. $start = isset($get['start']) ? htmlspecialchars($get['start']) : 0;
  219. $end = $start + $size;
  220. /* 获取文件列表 */
  221. $path = $dirname;
  222. $files = $this->getFiles($path,$allowFiles);
  223. if(!count($files)){
  224. return json_encode(array(
  225. "state" => "no match file",
  226. "list" => array(),
  227. "start" => $start,
  228. "total" => count($files)
  229. ));
  230. }
  231. /* 获取指定范围的列表 */
  232. $len = count($files);
  233. for($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){
  234. $list[] = $files[$i];
  235. }
  236. /* 返回数据 */
  237. $result = json_encode(array(
  238. "state" => "SUCCESS",
  239. "list" => $list,
  240. "start" => $start,
  241. "total" => count($files)
  242. ));
  243. return $result;
  244. }
  245. /*
  246. * 遍历获取目录下的指定类型的文件
  247. * @param $path
  248. * @param array $files
  249. * @return array
  250. */
  251. private function getFiles($path,$allowFiles,&$files = array()){
  252. if(!is_dir($path)) return null;
  253. if(substr($path,strlen($path)-1) != '/') $path .= '/';
  254. $handle = opendir($path);
  255. while(false !== ($file = readdir($handle))){
  256. if($file != '.' && $file != '..'){
  257. $path2 = $path.$file;
  258. if(is_dir($path2)){
  259. $this->getFiles($path2,$allowFiles,$files);
  260. }else{
  261. if(preg_match("/\.(".$allowFiles.")$/i",$file)){
  262. $files[] = array(
  263. 'url' => $path2, //substr($path2,1),
  264. 'mtime' => filemtime($path2)
  265. );
  266. }
  267. }
  268. }
  269. }
  270. return $files;
  271. }
  272. //抓取远程图片
  273. private function saveRemote($config,$fieldName){
  274. $imgUrl = htmlspecialchars($fieldName);
  275. $imgUrl = str_replace("&amp;","&",$imgUrl);
  276. //http开头验证
  277. if(strpos($imgUrl,"http") !== 0){
  278. $data=array(
  279. 'state' => '链接不是http链接',
  280. );
  281. return json_encode($data);
  282. }
  283. //获取请求头并检测死链
  284. $heads = get_headers($imgUrl);
  285. if(!(stristr($heads[0],"200") && stristr($heads[0],"OK"))){
  286. $data=array(
  287. 'state' => '链接不可用',
  288. );
  289. return json_encode($data);
  290. }
  291. //格式验证(扩展名验证和Content-Type验证)
  292. $fileType = strtolower(strrchr($imgUrl,'.'));
  293. if(!in_array($fileType,$config['allowFiles']) || stristr($heads['Content-Type'],"image")){
  294. $data=array(
  295. 'state' => '链接contentType不正确',
  296. );
  297. return json_encode($data);
  298. }
  299. //打开输出缓冲区并获取远程图片
  300. ob_start();
  301. $context = stream_context_create(
  302. array('http' => array(
  303. 'follow_location' => false // don't follow redirects
  304. ))
  305. );
  306. readfile($imgUrl,false,$context);
  307. $img = ob_get_contents();
  308. ob_end_clean();
  309. preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/",$imgUrl,$m);
  310. $dirname = UPLOAD . '/ueditor/image/'.date('Ymd');
  311. $file['oriName'] = $m ? $m[1] : "";
  312. $file['filesize'] = strlen($img);
  313. $file['ext'] = strtolower(strrchr($config['oriName'],'.'));
  314. $file['name'] = uniqid().$file['ext'];
  315. $file['fullName'] = $dirname.'/'.$file['name'];
  316. $fullName = $file['fullName'];
  317. //检查文件大小是否超出限制
  318. if($file['filesize'] >= ($config["maxSize"])){
  319. $data=array(
  320. 'state' => '文件大小超出网站限制',
  321. );
  322. return json_encode($data);
  323. }
  324. //创建目录失败
  325. if(!file_exists($dirname) && !mkdir($dirname,0777,true)){
  326. $data=array(
  327. 'state' => '目录创建失败',
  328. );
  329. return json_encode($data);
  330. }else if(!is_writeable($dirname)){
  331. $data=array(
  332. 'state' => '目录没有写权限',
  333. );
  334. return json_encode($data);
  335. }
  336. //移动文件
  337. if(!(file_put_contents($fullName, $img) && file_exists($fullName))){ //移动失败
  338. $data=array(
  339. 'state' => '写入文件内容错误',
  340. );
  341. return json_encode($data);
  342. }else{
  343. //先拉取到本地在上传到云端
  344. $upload_service = new Upload();
  345. $info = $upload_service->fileStore($dirname, $file['name']);
  346. if($info['code'] > 0){
  347. $file['fullName'] = $info['path'];
  348. }else{
  349. $data=array(
  350. 'state' => $info['message'],
  351. );
  352. return json_encode($data);
  353. }
  354. $data=array(
  355. 'state' => 'SUCCESS',
  356. 'url' => $file['fullName'],
  357. 'title' => $file['name'],
  358. 'original' => $file['oriName'],
  359. 'type' => $file['ext'],
  360. 'size' => $file['filesize'],
  361. );
  362. }
  363. return json_encode($data);
  364. }
  365. /*
  366. * 处理base64编码的图片上传
  367. * 例如:涂鸦图片上传
  368. */
  369. private function upBase64($config,$fieldName){
  370. $base64Data = $_POST[$fieldName];
  371. $img = base64_decode($base64Data);
  372. $dirname = UPLOAD . '/ueditor/scrawl/'.date('Ymd');
  373. $file['filesize'] = strlen($img);
  374. $file['oriName'] = $config['oriName'];
  375. $file['ext'] = strtolower(strrchr($config['oriName'],'.'));
  376. $file['name'] = uniqid().$file['ext'];
  377. $file['fullName'] = $dirname.'/'.$file['name'];
  378. $fullName = $file['fullName'];
  379. //检查文件大小是否超出限制
  380. if($file['filesize'] >= ($config["maxSize"])){
  381. $data=array(
  382. 'state' => '文件大小超出网站限制',
  383. );
  384. return json_encode($data);
  385. }
  386. //创建目录失败
  387. if(!file_exists($dirname) && !mkdir($dirname,0777,true)){
  388. $data=array(
  389. 'state' => '目录创建失败',
  390. );
  391. return json_encode($data);
  392. }else if(!is_writeable($dirname)){
  393. $data=array(
  394. 'state' => '目录没有写权限',
  395. );
  396. return json_encode($data);
  397. }
  398. //移动文件
  399. if(!(file_put_contents($fullName, $img) && file_exists($fullName))){ //移动失败
  400. $data=array(
  401. 'state' => '写入文件内容错误',
  402. );
  403. }else{
  404. //先拉取到本地在上传到云端
  405. $upload_service = new Upload();
  406. $info = $upload_service->fileStore($dirname, $file['name']);
  407. if($info['code'] > 0){
  408. $file['fullName'] = $info['path'];
  409. }else{
  410. $data=array(
  411. 'state' => $info['message'],
  412. );
  413. return json_encode($data);
  414. }
  415. $data=array(
  416. 'state' => 'SUCCESS',
  417. 'url' => substr($file['fullName'],1),
  418. 'title' => $file['name'],
  419. 'original' => $file['oriName'],
  420. 'type' => $file['ext'],
  421. 'size' => $file['filesize'],
  422. );
  423. }
  424. return json_encode($data);
  425. }
  426. }