<?php //index.php至于根目录有效；
namespace Admin\Controller;
use My\FileUtil;
use Think\Controller;

class UeditorController extends Controller {

	private $rootPath; //根目录位置
	private $savePath; //保存位置
	private $userid; //操作用户名

	public function _initialize() {
		FileUtil::connect(STORAGE_TYPE);

		if (session('?userid')) {
			$this->userid = session('username');
		} else {
			exit();
			//$this->userid='anybody';
		}
		$this->rootPath = '.';
		$this->savePath = '/uploads/';
	}

	public function index() {
		$CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents(CONF_PATH . "ueditor_config.json")), true);

		$action = htmlspecialchars($_GET['action']);
		switch ($action) {
			case 'config':
				$result = json_encode($CONFIG);
				break;

			/* 上传图片 */
			case 'uploadimage':
				$config = array(
					"pathFormat" => $CONFIG['imagePathFormat'],
					"maxSize"    => $CONFIG['imageMaxSize'],
					"allowFiles" => $CONFIG['imageAllowFiles'],
				);
				$fieldName = $CONFIG['imageFieldName'];
				$result    = $this->upFile($config, $fieldName, 'image');
				break;

			/* 上传涂鸦 */
			case 'uploadscrawl':
				$config = array(
					"pathFormat" => $CONFIG['scrawlPathFormat'],
					"maxSize"    => $CONFIG['scrawlMaxSize'],
					"allowFiles" => $CONFIG['scrawlAllowFiles'],
					"oriName"    => "scrawl.png",
				);
				$fieldName = $CONFIG['scrawlFieldName'];
				$base64    = "base64";
				$result    = $this->upBase64($config, $fieldName);
				break;

			/* 上传视频 */
			case 'uploadvideo':
				$config = array(
					"pathFormat" => $CONFIG['videoPathFormat'],
					"maxSize"    => $CONFIG['videoMaxSize'],
					"allowFiles" => $CONFIG['videoAllowFiles'],
				);
				$fieldName = $CONFIG['videoFieldName'];
				$result    = $this->upFile($config, $fieldName, 'video');
				break;

			/* 上传文件 */
			case 'uploadfile':
				// default:
				$config = array(
					"pathFormat" => $CONFIG['filePathFormat'],
					"maxSize"    => $CONFIG['fileMaxSize'],
					"allowFiles" => $CONFIG['fileAllowFiles'],
				);
				$fieldName = $CONFIG['fileFieldName'];
				$result    = $this->upFile($config, $fieldName, 'file');
				break;

			/* 列出图片 */
			case 'listimage':
				$allowFiles = $CONFIG['imageManagerAllowFiles'];
				$listSize   = $CONFIG['imageManagerListSize'];
				$path       = $CONFIG['imageManagerListPath'];
				//$get=$_GET;
				$result = $this->file_list($allowFiles, $listSize, $get, 'image');
				break;
			/* 列出文件 */
			case 'listfile':
				$allowFiles = $CONFIG['fileManagerAllowFiles'];
				$listSize   = $CONFIG['fileManagerListSize'];
				$path       = $CONFIG['fileManagerListPath'];
				$get        = $_GET;
				$result     = $this->file_list($allowFiles, $listSize, $get, 'file');
				break;

			/* 抓取远程文件 */
			/*
			case 'catchimage':
			$config = array(
			"pathFormat" => $CONFIG['catcherPathFormat'],
			"maxSize" => $CONFIG['catcherMaxSize'],
			"allowFiles" => $CONFIG['catcherAllowFiles'],
			"oriName" => "remote.png"
			);
			$fieldName = $CONFIG['catcherFieldName'];
			//抓取远程图片
			$list = array();
			if (isset($_POST[$fieldName])) {
			$source = $_POST[$fieldName];
			} else {
			$source = $_GET[$fieldName];
			}
			foreach ($source as $imgUrl) {
			$info=json_decode($this->saveRemote($config, $imgUrl),true);
			// dump($info);
			array_push($list, array(
			"state" => $info["state"],
			"url" => $info["url"],
			"size" => $info["size"],
			"title" => htmlspecialchars($info["title"]),
			"original" => htmlspecialchars($info["original"]),
			"source" => htmlspecialchars($imgUrl)
			));
			}

			$result= json_encode(array(
			'state'=> count($list) ? 'SUCCESS':'ERROR',
			'list'=> $list
			));
			break;
			 */

			default:
				$result = json_encode(array(
					'state' => '请求地址出错',
				));
				break;
		}

		/* 输出结果 */
		if (isset($_GET["callback"])) {
			if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
				echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
			} else {
				echo json_encode(array(
					'state' => 'callback参数不合法',
				));
			}
		} else {
			echo $result;
		}

	}
	/**
	 * 上传文件的主处理方法
	 * @return mixed
	 */
	private function upFile($config, $fieldName, $subName) {
		$conf = array(
			'rootPath' => $this->rootPath,
			'savePath' => $this->savePath,
			'autoSub'  => true,
			'subName'  => $this->userid . '/' . $subName,
			'maxSize'  => $config['maxSize'],
			'exts'     => $this->format_exts($config['allowFiles']), //去除扩展名前的点 .
		);
		$upload = new \Think\Upload($conf);
		$info   = $upload->uploadOne($_FILES[$fieldName]);
		if ($info) {
			switch ($subName) {
				case 'image':
					$fname       = $upload->rootPath . $info['savepath'] . $info['savename'];
					$thufname    = $upload->rootPath . $this->savePath . $this->userid . '/thu_image/thu_' . $info['savename'];
					$imagearr    = explode(',', 'jpg,gif,png,jpeg,bmp,ttf,tif');
					$info['ext'] = strtolower($info['ext']);
					$image       = new \Think\Image();
					$image->open($fname);
					$src_w   = $image->width();
					$src_h   = $image->height();
					$des_w   = $image->width();
					$des_w   = $image->width();
					$limit_w = 1024;
					$limit_h = 800;
					if ($src_w > $src_h) {
						if ($src_w > $limit_w) {
							$des_w = $limit_w;
							$des_h = ($src_w / $limit_w) * $src_h;
							$thu_w = 200;
							$thu_h = ($src_w / $thu_w) * $src_h;
							unlink($fname);
							$image->thumb($des_w, $des_h)->save($fname);
							$image->thumb($thu_w, $thu_h)->save($thufname);
						}
					} else {
						if ($src_h > $limit_h) {
							$thu_h = 180;
							$thu_w = ($src_h / $thu_h) * $src_w;
							$des_h = $limit_h;
							$des_w = ($src_h / $limit_h) * $src_w;
							unlink($fname);
							$image->thumb($des_w, $des_h)->save($fname);
							$image->thumb($thu_w, $thu_h)->save($thufname);

						}
					}
					break;
				default:
					# code...
					break;
			}
			$data = array(
				'state'    => 'SUCCESS',
				'url'      => FileUtil::encodeUrl($info['savepath'] . $info['savename']),
				'title'    => $info['savename'],
				'original' => $info['name'],
				'type'     => '.' . $info['ext'],
				'size'     => $info['size'],
			);
		} else {
			$data = array(
				'state' => $upload->getError(),
			);
		}
		return json_encode($data);
	}

	/**
	 * 处理base64编码的图片上传
	 * @return mixed
	 */
	/*
	private function upBase64($config,$fieldName)
	{
	$base64Data = $_POST[$fieldName];
	$img = base64_decode($base64Data);

	$dirname=$this->rootPath . $this->savePath . $this->userid . '/image/';
	$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 (!FileUtil::writeFile($fullName, $img)) { //移动失败
	$data=array(
	'state'=>'写入文件内容错误',
	);
	} else { //移动成功
	$data=array(
	'state'=>'SUCCESS',
	'url'=>FileUtil::encodeUrl($file['fullName']),
	'title'=>$file['name'],
	'original'=>$file['oriName'],
	'type'=>$file['ext'],
	'size'=>$file['filesize'],
	);
	}
	return json_encode($data);
	}*/

	/**
	 * 拉取远程图片
	 * @return mixed
	 */
	private function saveRemote($config, $fieldName) {
		$imgUrl = htmlspecialchars($fieldName);
		$imgUrl = str_replace("&amp;", "&", $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);
		}

		//初始化CURL并获取远程图片

		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $imgUrl);
		curl_setopt($curl, CURLOPT_HEADER, 0);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$img = curl_exec($curl);
		curl_close($curl);

		preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);

		$dirname          = $this->rootPath . $this->savePath . $this->userid . '/image/';
		$file['oriName']  = $m ? $m[1] : "";
		$file['filesize'] = strlen($img);
		$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 (!FileUtil::writeFile($fullName, $img)) {
			//移动失败
			$data = array(
				'state' => '写入文件内容错误',
			);
			return json_encode($data);
		} else {
			//移动成功
			$data = array(
				'state'    => 'SUCCESS',
				'url'      => FileUtil::encodeUrl($file['fullName']),
				'title'    => $file['name'],
				'original' => $file['oriName'],
				'type'     => $file['ext'],
				'size'     => $file['filesize'],
			);
		}
		return json_encode($data);
	}
	private function file_list($allowFiles, $listSize, $get, $subName) {
		$dirname = $this->rootPath . $this->savePath . $this->userid . '/' . $subName;

		$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 = $_SERVER['DOCUMENT_ROOT'] . (substr($path, 0, 1) == "/" ? "":"/") . $path;
		$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) {
		$content = FileUtil::getList($path);
		$files   = array();
		foreach ($content['files'] as $file) {
			if (preg_match("/\.(" . $allowFiles . ")$/i", $file['Name'])) {
				//array_push($files,array('url'=>FileUtil::encodeUrl($file['fullName']),'mtime'=>$file['uploadTime']));
				array_push($files, array('url' => $this->savePath . $this->userid . '/image/' . $file['Name'], 'mtime' => $file['uploadTime']));
			}
		}
		return $files;
	}
	/**
	 * [formatUrl 格式化url，用于将getfiles返回的文件路径进行格式化，起因是中文文件名的不支持浏览]
	 * @param  [type] $files [文件数组]
	 * @return [type]        [格式化后的文件数组]
	 */
	private function formatUrl($files) {
		if (!is_array($files)) {
			return $files;
		}

		foreach ($files as $key => $value) {
			$data = array();
			$data = explode('/', $value);
			foreach ($data as $k => $v) {
				if ('.' != $v && '..' != $v) {
					$data[$k] = urlencode($v);
					$data[$k] = str_replace("+", "%20", $data[$k]);
				}
			}
			$files[$key] = implode('/', $data);
		}
		return $files;
	}

	private function format_exts($exts) {
		$data = array();
		foreach ($exts as $key => $value) {
			$data[] = ltrim($value, '.');
		}
		return $data;
	}
}