UeditorController.class.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <?php
  2. /**
  3. * 百度编辑器控制器
  4. */
  5. namespace Admin\Controller;
  6. use Think\Controller;
  7. class UeditorController extends Controller{
  8. private $thumb;//缩略图模式(看手册)
  9. private $water; //是否加水印(0:无水印,1:水印文字,2水印图片)
  10. private $waterText;//水印文字
  11. private $waterPosition;//水印位置
  12. private $savePath; //保存位置
  13. private $userid; //操作用户名
  14. public function _initialize(){
  15. $this->userid=empty($_SESSION['userid'])? $_GET['userid'] : $_SESSION['userid'];
  16. if(empty($this->userid)){
  17. $this->userid= 'anonymity';
  18. }
  19. $this->rootPath= './Public/uploads/';
  20. $this->savePath='';
  21. $this->thumb=1;
  22. $this->water=1;
  23. $this->waterText='逐日软件';
  24. $this->waterPosition= 9;
  25. }
  26. public function index(){
  27. $CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents(CONF_PATH."config.json")), true);
  28. $action = htmlspecialchars($_GET['action']);
  29. switch ($action) {
  30. case 'config':
  31. $result = json_encode($CONFIG);
  32. break;
  33. /* 上传图片 */
  34. case 'uploadimage':
  35. $config = array(
  36. "pathFormat" => $CONFIG['imagePathFormat'],
  37. "maxSize" => $CONFIG['imageMaxSize'],
  38. "allowFiles" => $CONFIG['imageAllowFiles']
  39. );
  40. $fieldName = $CONFIG['imageFieldName'];
  41. $result=$this->upFile($config, $fieldName);
  42. break;
  43. /* 上传涂鸦 */
  44. case 'uploadscrawl':
  45. $config = array(
  46. "pathFormat" => $CONFIG['scrawlPathFormat'],
  47. "maxSize" => $CONFIG['scrawlMaxSize'],
  48. "allowFiles" => $CONFIG['scrawlAllowFiles'],
  49. "oriName" => "scrawl.png"
  50. );
  51. $fieldName = $CONFIG['scrawlFieldName'];
  52. $base64 = "base64";
  53. $result=$this->upBase64($config,$fieldName);
  54. break;
  55. /* 上传视频 */
  56. case 'uploadvideo':
  57. $config = array(
  58. "pathFormat" => $CONFIG['videoPathFormat'],
  59. "maxSize" => $CONFIG['videoMaxSize'],
  60. "allowFiles" => $CONFIG['videoAllowFiles']
  61. );
  62. $fieldName = $CONFIG['videoFieldName'];
  63. $result=$this->upFile($config, $fieldName);
  64. break;
  65. /* 上传文件 */
  66. case 'uploadfile':
  67. // default:
  68. $config = array(
  69. "pathFormat" => $CONFIG['filePathFormat'],
  70. "maxSize" => $CONFIG['fileMaxSize'],
  71. "allowFiles" => $CONFIG['fileAllowFiles']
  72. );
  73. $fieldName = $CONFIG['fileFieldName'];
  74. $result=$this->upFile($config, $fieldName);
  75. break;
  76. /* 列出图片 */
  77. case 'listimage':
  78. $allowFiles = $CONFIG['imageManagerAllowFiles'];
  79. $listSize = $CONFIG['imageManagerListSize'];
  80. $path = $CONFIG['imageManagerListPath'];
  81. $get=$_GET;
  82. $result =$this->file_list($allowFiles, $listSize, $get);
  83. break;
  84. /* 列出文件 */
  85. case 'listfile':
  86. $allowFiles = $CONFIG['fileManagerAllowFiles'];
  87. $listSize = $CONFIG['fileManagerListSize'];
  88. $path = $CONFIG['fileManagerListPath'];
  89. $get=$_GET;
  90. $result =$this->file_list($allowFiles, $listSize, $get);
  91. break;
  92. /* 抓取远程文件 */
  93. case 'catchimage':
  94. $config = array(
  95. "pathFormat" => $CONFIG['catcherPathFormat'],
  96. "maxSize" => $CONFIG['catcherMaxSize'],
  97. "allowFiles" => $CONFIG['catcherAllowFiles'],
  98. "oriName" => "remote.png"
  99. );
  100. $fieldName = $CONFIG['catcherFieldName'];
  101. /* 抓取远程图片 */
  102. $list = array();
  103. if (isset($_POST[$fieldName])) {
  104. $source = $_POST[$fieldName];
  105. } else {
  106. $source = $_GET[$fieldName];
  107. }
  108. foreach ($source as $imgUrl) {
  109. $info=json_decode($this->saveRemote($config, $imgUrl),true);
  110. // dump($info);
  111. array_push($list, array(
  112. "state" => $info["state"],
  113. "url" => $info["url"],
  114. "size" => $info["size"],
  115. "title" => htmlspecialchars($info["title"]),
  116. "original" => htmlspecialchars($info["original"]),
  117. "source" => htmlspecialchars($imgUrl)
  118. ));
  119. }
  120. $result= json_encode(array(
  121. 'state'=> count($list) ? 'SUCCESS':'ERROR',
  122. 'list'=> $list
  123. ));
  124. break;
  125. default:
  126. $result = json_encode(array(
  127. 'state'=> '请求地址出错'
  128. ));
  129. break;
  130. }
  131. /* 输出结果 */
  132. if (isset($_GET["callback"])) {
  133. if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
  134. echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
  135. } else {
  136. echo json_encode(array(
  137. 'state'=> 'callback参数不合法'
  138. ));
  139. }
  140. } else {
  141. echo $result;
  142. }
  143. }
  144. /**
  145. * 上传文件的主处理方法
  146. * @return mixed
  147. */
  148. private function upFile($config,$fieldName){
  149. $conf=array(
  150. 'rootPath' => $this->rootPath,
  151. 'savePath' => $this->savePath,
  152. 'autoSub' => true,
  153. 'subName'=>$this->userid . '/' . date('Ym',time()) ,// 子目录命名的规则为 用户名/年月/
  154. 'maxSize'=>$config['maxSize'],
  155. 'exts'=>$this->format_exts($config['allowFiles']),//去除扩展名前的点 .
  156. );
  157. $upload=new \Think\Upload($conf);
  158. $info=$upload->uploadOne($_FILES[$fieldName]);
  159. if($info){
  160. $fname=$upload->rootPath .$info['savepath'].$info['savename'];
  161. $imagearr = explode(',', 'jpg,gif,png,jpeg,bmp,ttf,tif');
  162. $info['ext']= strtolower($info['ext']);
  163. $isimage = in_array($info['ext'],$imagearr) ? 1 : 0;
  164. if ($isimage) {
  165. $image=new \Think\Image();
  166. $image->Open($fname);
  167. $image->thumb(680,680,$this->thumb)->save($fname);
  168. if ($this->water==1) {
  169. $image->text($this->waterText,'./Public/font/STXINGKA.TTF',18,'#9a9a9a',$this->waterPosition,array(-2,0))->save($fname);
  170. }
  171. if ($this->water==2) {
  172. $image->water($this->waterImage)->save($fname);
  173. }
  174. }
  175. $data=array(
  176. 'state'=>'SUCCESS',
  177. //'url'=>__ROOT__. strtolower(substr($fname,1)),
  178. 'url'=>C('WEB_HOST'). strtolower(substr($fname,1)),
  179. 'title'=>$info['savename'],
  180. 'original'=>$info['name'],
  181. 'type'=>'.' . $info['ext'],
  182. 'size'=>$info['size'],
  183. );
  184. }else{
  185. $data=array(
  186. 'state'=>$upload->getError(),
  187. );
  188. }
  189. return json_encode($data);
  190. }
  191. /**
  192. * 处理base64编码的图片上传
  193. * @return mixed
  194. */
  195. private function upBase64($config,$fieldName)
  196. {
  197. $base64Data = $_POST[$fieldName];
  198. $img = base64_decode($base64Data);
  199. $dirname=$this->rootPath . $this->savePath . $this->userid . '/scrawl/';
  200. $file['filesize']=strlen($img);
  201. $file['oriName']=$config['oriName'];
  202. $file['ext']=strtolower(strrchr($config['oriName'], '.'));
  203. $file['name']= uniqid() . $file['ext'];
  204. $file['fullName']=$dirname . $file['name'];
  205. $fullName=$file['fullName'];
  206. // dump($file);
  207. //检查文件大小是否超出限制
  208. if ($file['filesize'] >= ($config["maxSize"])) {
  209. $data=array(
  210. 'state'=>'文件大小超出网站限制',
  211. );
  212. return json_encode($data);
  213. }
  214. //创建目录失败
  215. if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
  216. $data=array(
  217. 'state'=>'目录创建失败',
  218. );
  219. return json_encode($data);
  220. } else if (!is_writeable($dirname)) {
  221. $data=array(
  222. 'state'=>'目录没有写权限',
  223. );
  224. return json_encode($data);
  225. }
  226. //移动文件
  227. if (!(file_put_contents($fullName, $img) && file_exists($fullName))) { //移动失败
  228. $data=array(
  229. 'state'=>'写入文件内容错误',
  230. );
  231. } else { //移动成功
  232. $data=array(
  233. 'state'=>'SUCCESS',
  234. 'url'=>__ROOT__ . substr($file['fullName'],1),
  235. 'title'=>$file['name'],
  236. 'original'=>$file['oriName'],
  237. 'type'=>$file['ext'],
  238. 'size'=>$file['filesize'],
  239. );
  240. }
  241. return json_encode($data);
  242. }
  243. /**
  244. * 拉取远程图片
  245. * @return mixed
  246. */
  247. private function saveRemote($config, $fieldName)
  248. {
  249. $imgUrl = htmlspecialchars($fieldName);
  250. $imgUrl = str_replace("&amp;", "&", $imgUrl);
  251. //http开头验证
  252. if (strpos($imgUrl, "http") !== 0) {
  253. $data=array(
  254. 'state'=>'链接不是http链接',
  255. );
  256. return json_encode($data);
  257. }
  258. //获取请求头并检测死链
  259. $heads = get_headers($imgUrl);
  260. if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
  261. $data=array(
  262. 'state'=>'链接不可用',
  263. );
  264. return json_encode($data);
  265. }
  266. //格式验证(扩展名验证和Content-Type验证)
  267. $fileType = strtolower(strrchr($imgUrl, '.'));
  268. if (!in_array($fileType, $config['allowFiles']) || stristr($heads['Content-Type'], "image")) {
  269. $data=array(
  270. 'state'=>'链接contentType不正确',
  271. );
  272. return json_encode($data);
  273. }
  274. //打开输出缓冲区并获取远程图片
  275. ob_start();
  276. $context = stream_context_create(
  277. array('http' => array(
  278. 'follow_location' => false // don't follow redirects
  279. ))
  280. );
  281. readfile($imgUrl, false, $context);
  282. $img = ob_get_contents();
  283. ob_end_clean();
  284. preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);
  285. $dirname=$this->rootPath . $this->savePath . $this->userid . '/remote/';
  286. $file['oriName']=$m ? $m[1]:"";
  287. $file['filesize']=strlen($img);
  288. $file['ext']=strtolower(strrchr($config['oriName'], '.'));
  289. $file['name']= uniqid() . $file['ext'];
  290. $file['fullName']=$dirname . $file['name'];
  291. $fullName=$file['fullName'];
  292. //检查文件大小是否超出限制
  293. if ($file['filesize'] >= ($config["maxSize"])) {
  294. $data=array(
  295. 'state'=>'文件大小超出网站限制',
  296. );
  297. return json_encode($data);
  298. }
  299. //创建目录失败
  300. if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
  301. $data=array(
  302. 'state'=>'目录创建失败',
  303. );
  304. return json_encode($data);
  305. } else if (!is_writeable($dirname)) {
  306. $data=array(
  307. 'state'=>'目录没有写权限',
  308. );
  309. return json_encode($data);
  310. }
  311. //移动文件
  312. if (!(file_put_contents($fullName, $img) && file_exists($fullName))) { //移动失败
  313. $data=array(
  314. 'state'=>'写入文件内容错误',
  315. );
  316. return json_encode($data);
  317. } else { //移动成功
  318. $data=array(
  319. 'state'=>'SUCCESS',
  320. 'url'=>__ROOT__ . substr($file['fullName'],1),
  321. 'title'=>$file['name'],
  322. 'original'=>$file['oriName'],
  323. 'type'=>$file['ext'],
  324. 'size'=>$file['filesize'],
  325. );
  326. }
  327. return json_encode($data);
  328. }
  329. private function file_list($allowFiles, $listSize, $get){
  330. $dirname=$this->rootPath . $this->savePath ;
  331. if ($this->userid!='admin') {
  332. $dirname.=$this->userid . '/';
  333. }
  334. $allowFiles = substr(str_replace(".", "|", join("", $allowFiles)), 1);
  335. /* 获取参数 */
  336. $size = isset($get['size']) ? htmlspecialchars($get['size']) : $listSize;
  337. $start = isset($get['start']) ? htmlspecialchars($get['start']) : 0;
  338. $end = $start + $size;
  339. /* 获取文件列表 */
  340. // $path = $_SERVER['DOCUMENT_ROOT'] . (substr($path, 0, 1) == "/" ? "":"/") . $path;
  341. $path=$dirname;
  342. $files = $this->getfiles($path, $allowFiles);
  343. if (!count($files)) {
  344. return json_encode(array(
  345. "state" => "no match file",
  346. "list" => array(),
  347. "start" => $start,
  348. "total" => count($files)
  349. ));
  350. }
  351. /* 获取指定范围的列表 */
  352. $len = count($files);
  353. for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){
  354. $list[] = $files[$i];
  355. }
  356. //倒序
  357. //for ($i = $end, $list = array(); $i < $len && $i < $end; $i++){
  358. // $list[] = $files[$i];
  359. //}
  360. /* 返回数据 */
  361. $result = json_encode(array(
  362. "state" => "SUCCESS",
  363. "list" => $list,
  364. "start" => $start,
  365. "total" => count($files)
  366. ));
  367. return $result;
  368. }
  369. /**
  370. * 遍历获取目录下的指定类型的文件
  371. * @param $path
  372. * @param array $files
  373. * @return array
  374. */
  375. private function getfiles( $path , $allowFiles, &$files = array() ) {
  376. if ( !is_dir( $path ) ) return null;
  377. if(substr($path, strlen($path) - 1) != '/') $path .= '/';
  378. $handle = opendir( $path);
  379. while ( false !== ( $file = readdir( $handle ) ) ) {
  380. if ( $file != '.' && $file != '..' ) {
  381. $path2 = $path . $file;
  382. if ( is_dir( $path2)) {
  383. $this->getfiles( $path2 ,$allowFiles, $files );
  384. } else {
  385. if (preg_match("/\.(".$allowFiles.")$/i", $file)) {
  386. $files[] = array(
  387. 'url'=> __ROOT__ . substr($path2, 1),
  388. 'mtime'=> filemtime($path2)
  389. );
  390. }
  391. }
  392. }
  393. }
  394. return $files;
  395. }
  396. /**
  397. * [formatUrl 格式化url,用于将getfiles返回的文件路径进行格式化,起因是中文文件名的不支持浏览]
  398. * @param [type] $files [文件数组]
  399. * @return [type] [格式化后的文件数组]
  400. */
  401. private function formatUrl($files){
  402. if(!is_array($files)) return $files;
  403. foreach ($files as $key => $value) {
  404. $data=array();
  405. $data=explode('/', $value);
  406. foreach ($data as $k=>$v) {
  407. if($v!='.' && $v!='..'){
  408. $data[$k]=urlencode($v);
  409. $data[$k] = str_replace("+", "%20", $data[$k]);
  410. }
  411. }
  412. $files[$key]=implode('/', $data);
  413. }
  414. return $files;
  415. }
  416. private function format_exts($exts){
  417. $data=array();
  418. foreach ($exts as $key => $value) {
  419. $data[]=ltrim($value,'.');
  420. }
  421. return $data;
  422. }
  423. }
  424. ?>