<?php
/**
 * [WeEngine System] Copyright (c) 2014 WE7.CC
 * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
 */
defined('IN_IA') or exit('Access Denied');


function file_write($filename, $data) {
	global $_W;
	$filename = ATTACHMENT_ROOT . '/' . $filename;
	mkdirs(dirname($filename));
	file_put_contents($filename, $data);
	@chmod($filename, $_W['config']['setting']['filemode']);

	return is_file($filename);
}
function file_read($filename) {
	global $_W;
	$filename = ATTACHMENT_ROOT . '/' . $filename;
	if (!is_file($filename)) {
		return false;
	}

	return file_get_contents($filename);
}

function file_move($filename, $dest) {
	global $_W;
	mkdirs(dirname($dest));
	if (is_uploaded_file($filename)) {
		move_uploaded_file($filename, $dest);
	} else {
		rename($filename, $dest);
	}
	@chmod($filename, $_W['config']['setting']['filemode']);

	return is_file($dest);
}


function file_tree($path, $include = array()) {
	$files = array();
	if (!empty($include)) {
		$ds = glob($path . '/{' . implode(',', $include) . '}', GLOB_BRACE);
	} else {
		$ds = glob($path . '/*');
	}
	if (is_array($ds)) {
		foreach ($ds as $entry) {
			if (is_file($entry)) {
				$files[] = $entry;
			}
			if (is_dir($entry)) {
				$rs = file_tree($entry);
				foreach ($rs as $f) {
					$files[] = $f;
				}
			}
		}
	}
	
	return $files;
}


function file_tree_limit($path, $limit = 0, $acquired_files_count = 0) {
	$files = array();
	if (is_dir($path)){
		if ($dir = opendir($path)){
			while (($file = readdir($dir)) !== false){
				if (in_array($file, array('.', '..'))) {
					continue;
				}
				if (is_file($path . '/' . $file)) {
					$files[] = $path . '/' . $file;
					$acquired_files_count++;
					if ($limit > 0 && $acquired_files_count >= $limit) {
						closedir($dir);
						return $files;
					}
				}
				if (is_dir($path . '/' . $file)) {
					$rs = file_tree_limit($path . '/' . $file, $limit, $acquired_files_count);
					foreach ($rs as $f) {
						$files[] = $f;
						$acquired_files_count++;
						if ($limit > 0 && $acquired_files_count >= $limit) {
							closedir($dir);
							return $files;
						}
					}
				}
			}
			closedir($dir);
		}
	}
	return $files;
}


function file_dir_exist_image($path) {
	if (is_dir($path)){
		if ($dir = opendir($path)){
			while (($file = readdir($dir)) !== false){
				if (in_array($file, array('.', '..'))) {
					continue;
				}
				if (is_file($path . '/' . $file) && file_is_image($path . '/' . $file)) {
					if (strpos($path, ATTACHMENT_ROOT) === 0) {
						$attachment = str_replace(ATTACHMENT_ROOT . 'images/', '', $path . '/' .$file);
						list($file_account) = explode('/', $attachment);
						if ($file_account == 'global') {
							continue;
						}
					}
					closedir($dir);
					return true;
				}
				if (is_dir($path . '/' . $file) && file_dir_exist_image($path . '/' . $file)) {
					closedir($dir);
					return true;
				}
			}
			closedir($dir);
		}
	}
	return false;
}


function mkdirs($path) {
	if (!is_dir($path)) {
		mkdirs(dirname($path));
		mkdir($path);
	}

	return is_dir($path);
}


function file_copy($src, $des, $filter) {
	$dir = opendir($src);
	@mkdir($des);
	while (false !== ($file = readdir($dir))) {
		if (($file != '.') && ($file != '..')) {
			if (is_dir($src . '/' . $file)) {
				file_copy($src . '/' . $file, $des . '/' . $file, $filter);
			} elseif (!in_array(substr($file, strrpos($file, '.') + 1), $filter)) {
				copy($src . '/' . $file, $des . '/' . $file);
			}
		}
	}
	closedir($dir);
}


function rmdirs($path, $clean = false) {
	if (!is_dir($path)) {
		return false;
	}
	$files = glob($path . '/*');
	if ($files) {
		foreach ($files as $file) {
			is_dir($file) ? rmdirs($file) : @unlink($file);
		}
	}

	return $clean ? true : @rmdir($path);
}


function file_upload($file, $type = 'image', $name = '', $compress = false) {
	$harmtype = array('asp', 'php', 'jsp', 'js', 'css', 'php3', 'php4', 'php5', 'ashx', 'aspx', 'exe', 'cgi');
	if (empty($file)) {
		return error(-1, '没有上传内容');
	}
	if (!in_array($type, array('image', 'thumb', 'voice', 'video', 'audio'))) {
		return error(-2, '未知的上传类型');
	}
	global $_W;
	$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
	$ext = strtolower($ext);
	$setting = setting_load('upload');
	switch ($type) {
		case 'image':
		case 'thumb':
			$allowExt = array('gif', 'jpg', 'jpeg', 'bmp', 'png', 'ico');
			$limit = $setting['upload']['image']['limit'];
			break;
		case 'voice':
		case 'audio':
			$allowExt = array('mp3', 'wma', 'wav', 'amr');
			$limit = $setting['upload']['audio']['limit'];
			break;
		case 'video':
			$allowExt = array('rm', 'rmvb', 'wmv', 'avi', 'mpg', 'mpeg', 'mp4');
			$limit = $setting['upload']['audio']['limit'];
			break;
	}
	$setting = $_W['setting']['upload'][$type];
	if (!empty($setting)) {
		$allowExt = array_merge($setting['extentions'], $allowExt);
	}
	if (!in_array(strtolower($ext), $allowExt) || in_array(strtolower($ext), $harmtype)) {
		return error(-3, '不允许上传此类文件');
	}
	if (!empty($limit) && $limit * 1024 < filesize($file['tmp_name'])) {
		return error(-4, "上传的文件超过大小限制，请上传小于 {$limit}k 的文件");
	}



	$result = array();
	if (empty($name) || $name == 'auto') {
		$uniacid = intval($_W['uniacid']);
		$path = "{$type}s/{$uniacid}/" . date('Y/m/');
		mkdirs(ATTACHMENT_ROOT . '/' . $path);
		$filename = file_random_name(ATTACHMENT_ROOT . '/' . $path, $ext);

		$result['path'] = $path . $filename;
	} else {
		mkdirs(dirname(ATTACHMENT_ROOT . '/' . $name));
		if (!strexists($name, $ext)) {
			$name .= '.' . $ext;
		}
		$result['path'] = $name;
	}

	$save_path = ATTACHMENT_ROOT . '/' . $result['path'];
	if (!file_move($file['tmp_name'], $save_path)) {
		return error(-1, '保存上传文件失败');
	}

	if ($type == 'image' && $compress) {
				file_image_quality($save_path, $save_path, $ext);
	}

	$result['success'] = true;

	return $result;
}
function file_wechat_upload($file, $type = 'image', $name = '') {
	$harmtype = array('asp', 'php', 'jsp', 'js', 'css', 'php3', 'php4', 'php5', 'ashx', 'aspx', 'exe', 'cgi');
	if (empty($file)) {
		return error(-1, '没有上传内容');
	}
	if (!in_array($type, array('image', 'thumb', 'voice', 'video', 'audio'))) {
		return error(-2, '未知的上传类型');
	}

	global $_W;
	$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
	$ext = strtolower($ext);
	if (in_array(strtolower($ext), $harmtype)) {
		return error(-3, '不允许上传此类文件');
	}



	$result = array();
	if (empty($name) || $name == 'auto') {
		$uniacid = intval($_W['uniacid']);
		$path = "{$type}s/{$uniacid}/" . date('Y/m/');
		mkdirs(ATTACHMENT_ROOT . '/' . $path);
		$filename = file_random_name(ATTACHMENT_ROOT . '/' . $path, $ext);
		$result['path'] = $path . $filename;
	} else {
		mkdirs(dirname(ATTACHMENT_ROOT . '/' . $name));
		if (!strexists($name, $ext)) {
			$name .= '.' . $ext;
		}
		$result['path'] = $name;
	}
	$save_path = ATTACHMENT_ROOT . '/' . $result['path'];
	if (!file_move($file['tmp_name'], $save_path)) {
		return error(-1, '保存上传文件失败');
	}

	if ($type == 'image') {
				file_image_quality($save_path, $save_path, $ext);
	}
	$result['success'] = true;

	return $result;
}


function file_remote_upload($filename, $auto_delete_local = true) {
	global $_W;
	if (empty($_W['setting']['remote']['type'])) {
		return false;
	}
	if ($_W['setting']['remote']['type'] == '1') {
		load()->library('ftp');
		$ftp_config = array(
			'hostname' => $_W['setting']['remote']['ftp']['host'],
			'username' => $_W['setting']['remote']['ftp']['username'],
			'password' => $_W['setting']['remote']['ftp']['password'],
			'port' => $_W['setting']['remote']['ftp']['port'],
			'ssl' => $_W['setting']['remote']['ftp']['ssl'],
			'passive' => $_W['setting']['remote']['ftp']['pasv'],
			'timeout' => $_W['setting']['remote']['ftp']['timeout'],
			'rootdir' => $_W['setting']['remote']['ftp']['dir'],
		);
		$ftp = new Ftp($ftp_config);
		if (true === $ftp->connect()) {
			$response = $ftp->upload(ATTACHMENT_ROOT . '/' . $filename, $filename);
			if ($auto_delete_local) {
				file_delete($filename);
			}
			if (!empty($response)) {
				return true;
			} else {
				return error(1, '远程附件上传失败，请检查配置并重新上传');
			}
		} else {
			return error(1, '远程附件上传失败，请检查配置并重新上传');
		}
	} elseif ($_W['setting']['remote']['type'] == '2') {
		load()->library('oss');
		load()->model('attachment');
		$buckets = attachment_alioss_buctkets($_W['setting']['remote']['alioss']['key'], $_W['setting']['remote']['alioss']['secret']);
		$host_name = $_W['setting']['remote']['alioss']['internal'] ? '-internal.aliyuncs.com' : '.aliyuncs.com';
		$endpoint = 'http://' . $buckets[$_W['setting']['remote']['alioss']['bucket']]['location'] . $host_name;
		try {
			$ossClient = new \OSS\OssClient($_W['setting']['remote']['alioss']['key'], $_W['setting']['remote']['alioss']['secret'], $endpoint);
			$ossClient->uploadFile($_W['setting']['remote']['alioss']['bucket'], $filename, ATTACHMENT_ROOT . $filename);
		} catch (\OSS\Core\OssException $e) {
			return error(1, $e->getMessage());
		}
		if ($auto_delete_local) {
			file_delete($filename);
		}
	} elseif ($_W['setting']['remote']['type'] == '3') {
		load()->library('qiniu');
		$auth = new Qiniu\Auth($_W['setting']['remote']['qiniu']['accesskey'], $_W['setting']['remote']['qiniu']['secretkey']);
		$config = new Qiniu\Config();
		$uploadmgr = new Qiniu\Storage\UploadManager($config);
				$putpolicy = Qiniu\base64_urlSafeEncode(json_encode(array(
			'scope' => $_W['setting']['remote']['qiniu']['bucket'] . ':' . $filename,
		)));
		$uploadtoken = $auth->uploadToken($_W['setting']['remote']['qiniu']['bucket'], $filename, 3600, $putpolicy);
		list($ret, $err) = $uploadmgr->putFile($uploadtoken, $filename, ATTACHMENT_ROOT . '/' . $filename);
		if ($auto_delete_local) {
			file_delete($filename);
		}
		if ($err !== null) {
			return error(1, '远程附件上传失败，请检查配置并重新上传');
		} else {
			return true;
		}
	} elseif ($_W['setting']['remote']['type'] == '4') {
		if (!empty($_W['setting']['remote']['cos']['local'])) {
			load()->library('cos');
			qcloudcos\Cosapi::setRegion($_W['setting']['remote']['cos']['local']);
			$uploadRet = qcloudcos\Cosapi::upload($_W['setting']['remote']['cos']['bucket'], ATTACHMENT_ROOT . $filename, '/' . $filename, '', 3 * 1024 * 1024, 0);
		} else {
			load()->library('cosv3');
			$uploadRet = \Qcloud_cos\Cosapi::upload($_W['setting']['remote']['cos']['bucket'], ATTACHMENT_ROOT . $filename, '/' . $filename, '', 3 * 1024 * 1024, 0);
		}
		if ($uploadRet['code'] != 0) {
			switch ($uploadRet['code']) {
				case -62:
					$message = '输入的appid有误';
					break;
				case -79:
					$message = '输入的SecretID有误';
					break;
				case -97:
					$message = '输入的SecretKEY有误';
					break;
				case -166:
					$message = '输入的bucket有误';
					break;
			}

			return error(-1, $message);
		}
		if ($auto_delete_local) {
			file_delete($filename);
		}
	}
}


function file_dir_remote_upload($dir_path, $limit = 50) {
	global $_W;
	if (empty($_W['setting']['remote']['type'])) {
		return error(1, '未开启远程附件');
	}
	$dir_path = safe_gpc_path($dir_path);
	if (!empty($dir_path)) {
		$local_attachment = file_tree_limit($dir_path, $limit);
	} else {
		$local_attachment = array();
	}
	if (is_array($local_attachment) && !empty($local_attachment)) {
		foreach ($local_attachment as $attachment) {
			$filename = str_replace(ATTACHMENT_ROOT, '', $attachment);
			list($image_dir, $file_account) = explode('/', $filename);
			if ($file_account == 'global' || !file_is_image($attachment)) {
				continue;
			}
			if (is_numeric($file_account) && is_dir(ATTACHMENT_ROOT . 'images/' . $file_account) && !empty($_W['setting']['remote_complete_info'][$file_account]['type'])) {
				$_W['setting']['remote'] = $_W['setting']['remote_complete_info'][$file_account];
			} else {
				$_W['setting']['remote'] = $_W['setting']['remote_complete_info'];
			}
			$result = file_remote_upload($filename);
			if (is_error($result)) {
				return $result;
			}
		}
	}
	return true;
}


function file_random_name($dir, $ext) {
	do {
		$filename = random(30) . '.' . $ext;
	} while (file_exists($dir . $filename));

	return $filename;
}


function file_delete($file) {
	if (empty($file)) {
		return false;
	}
	if (file_exists($file)) {
		@unlink($file);
	}
	if (file_exists(ATTACHMENT_ROOT . '/' . $file)) {
		@unlink(ATTACHMENT_ROOT . '/' . $file);
	}

	return true;
}
function file_remote_delete($file) {
	global $_W;
	if (empty($file)) {
		return true;
	}
	if ($_W['setting']['remote']['type'] == '1') {
		load()->library('ftp');
		$ftp_config = array(
			'hostname' => $_W['setting']['remote']['ftp']['host'],
			'username' => $_W['setting']['remote']['ftp']['username'],
			'password' => $_W['setting']['remote']['ftp']['password'],
			'port' => $_W['setting']['remote']['ftp']['port'],
			'ssl' => $_W['setting']['remote']['ftp']['ssl'],
			'passive' => $_W['setting']['remote']['ftp']['pasv'],
			'timeout' => $_W['setting']['remote']['ftp']['timeout'],
			'rootdir' => $_W['setting']['remote']['ftp']['dir'],
		);
		$ftp = new Ftp($ftp_config);
		if (true === $ftp->connect()) {
			if ($ftp->delete_file($file)) {
				return true;
			} else {
				return error(1, '删除附件失败，请检查配置并重新删除');
			}
		} else {
			return error(1, '删除附件失败，请检查配置并重新删除');
		}
	} elseif ($_W['setting']['remote']['type'] == '2') {
		load()->model('attachment');
		load()->library('oss');
		$buckets = attachment_alioss_buctkets($_W['setting']['remote']['alioss']['key'], $_W['setting']['remote']['alioss']['secret']);
		$endpoint = 'http://' . $buckets[$_W['setting']['remote']['alioss']['bucket']]['location'] . '.aliyuncs.com';
		try {
			$ossClient = new \OSS\OssClient($_W['setting']['remote']['alioss']['key'], $_W['setting']['remote']['alioss']['secret'], $endpoint);
			$ossClient->deleteObject($_W['setting']['remote']['alioss']['bucket'], $file);
		} catch (\OSS\Core\OssException $e) {
			return error(1, '删除oss远程文件失败');
		}
	} elseif ($_W['setting']['remote']['type'] == '3') {
		load()->library('qiniu');
		$auth = new Qiniu\Auth($_W['setting']['remote']['qiniu']['accesskey'], $_W['setting']['remote']['qiniu']['secretkey']);
		$bucketMgr = new Qiniu\Storage\BucketManager($auth);
		$error = $bucketMgr->delete($_W['setting']['remote']['qiniu']['bucket'], $file);
		if ($error instanceof Qiniu\Http\Error) {
			if ($error->code() == 612) {
				return true;
			}

			return error(1, '删除七牛远程文件失败');
		} else {
			return true;
		}
	} elseif ($_W['setting']['remote']['type'] == '4') {
		$bucketName = $_W['setting']['remote']['cos']['bucket'];
		$path = '/' . $file;
		if (!empty($_W['setting']['remote']['cos']['local'])) {
			load()->library('cos');
			qcloudcos\Cosapi::setRegion($_W['setting']['remote']['cos']['local']);
			$result = qcloudcos\Cosapi::delFile($bucketName, $path);
		} else {
			load()->library('cosv3');
			$result = Qcloud_cos\Cosapi::delFile($bucketName, $path);
		}
		if (!empty($result['code'])) {
			return error(-1, '删除cos远程文件失败');
		} else {
			return true;
		}
	}

	return true;
}


function file_image_thumb($srcfile, $desfile = '', $width = 0) {
	global $_W;
	load()->classs('image');
	if (intval($width) == 0) {
		load()->model('setting');
		$width = intval($_W['setting']['upload']['image']['width']);
	}
	if (empty($desfile)) {
		$ext = pathinfo($srcfile, PATHINFO_EXTENSION);
		$srcdir = dirname($srcfile);
		do {
			$desfile = $srcdir . '/' . random(30) . ".{$ext}";
		} while (file_exists($desfile));
	}

	$des = dirname($desfile);
		if (!file_exists($des)) {
		if (!mkdirs($des)) {
			return error('-1', '创建目录失败');
		}
	} elseif (!is_writable($des)) {
		return error('-1', '目录无法写入');
	}
		$org_info = @getimagesize($srcfile);
	if ($org_info) {
		if ($width == 0 || $width > $org_info[0]) {
			copy($srcfile, $desfile);
			return str_replace(ATTACHMENT_ROOT . '/', '', $desfile);
		}
	}
		$scale_org = $org_info[0] / $org_info[1];
		$height = $width / $scale_org;
	$desfile = Image::create($srcfile)->resize($width, $height)->saveTo($desfile);
	if (!$desfile) {
		return false;
	}

	return str_replace(ATTACHMENT_ROOT . '/', '', $desfile);
}


function file_image_crop($src, $desfile, $width = 400, $height = 300, $position = 1) {
	load()->classs('image');
	$des = dirname($desfile);
		if (!file_exists($des)) {
		if (!mkdirs($des)) {
			return error('-1', '创建目录失败');
		}
	} elseif (!is_writable($des)) {
		return error('-1', '目录无法写入');
	}

	return Image::create($src)
		->crop($width, $height, $position)
		->saveTo($desfile);
}


function file_lists($filepath, $subdir = 1, $ex = '', $isdir = 0, $md5 = 0, $enforcement = 0) {
	static $file_list = array();
	if ($enforcement) {
		$file_list = array();
	}
	$flags = $isdir ? GLOB_ONLYDIR : 0;
	$list = glob($filepath . '*' . (!empty($ex) && empty($subdir) ? '.' . $ex : ''), $flags);
	if (!empty($ex)) {
		$ex_num = strlen($ex);
	}
	foreach ($list as $k => $v) {
		$v = str_replace('\\', '/', $v);
		$v1 = str_replace(IA_ROOT . '/', '', $v);
		if ($subdir && is_dir($v)) {
			file_lists($v . '/', $subdir, $ex, $isdir, $md5);
			continue;
		}
		if (!empty($ex) && strtolower(substr($v, -$ex_num, $ex_num)) == $ex) {
			if ($md5) {
				$file_list[$v1] = md5_file($v);
			} else {
				$file_list[] = $v1;
			}
			continue;
		} elseif (!empty($ex) && strtolower(substr($v, -$ex_num, $ex_num)) != $ex) {
			unset($list[$k]);
			continue;
		}
	}

	return $file_list;
}


function file_remote_attach_fetch($url, $limit = 0, $path = '') {
	global $_W;
	$url = trim($url);
	if (empty($url)) {
		return error(-1, '文件地址不存在');
	}
	load()->func('communication');
	$resp = ihttp_get($url);

	if (is_error($resp)) {
		return error(-1, '提取文件失败, 错误信息: ' . $resp['message']);
	}
	if (intval($resp['code']) != 200) {
		return error(-1, '提取文件失败: 未找到该资源文件.');
	}
	$ext = $type = '';
	switch ($resp['headers']['Content-Type']) {
		case 'application/x-jpg':
		case 'image/jpg':
		case 'image/jpeg':
			$ext = 'jpg';
			$type = 'images';
			break;
		case 'image/png':
			$ext = 'png';
			$type = 'images';
			break;
		case 'image/gif':
			$ext = 'gif';
			$type = 'images';
			break;
		case 'video/mp4':
		case 'video/mpeg4':
			$ext = 'mp4';
			$type = 'videos';
			break;
		case 'video/x-ms-wmv':
			$ext = 'wmv';
			$type = 'videos';
			break;
		case 'audio/mpeg':
			$ext = 'mp3';
			$type = 'audios';
			break;
		case 'audio/mp4':
			$ext = 'mp4';
			$type = 'audios';
			break;
		case 'audio/x-ms-wma':
			$ext = 'wma';
			$type = 'audios';
			break;
		default:
			return error(-1, '提取资源失败, 资源文件类型错误.');
			break;
	}
	if (empty($path)) {
		$path = $type . "/{$_W['uniacid']}/" . date('Y/m/');
	} else {
		$path = parse_path($path);
	}
	if (!$path) {
		return error(-1, '提取文件失败: 上传路径配置有误.');
	}

	if (! is_dir(ATTACHMENT_ROOT . $path)) {
		if (! mkdirs(ATTACHMENT_ROOT . $path, 0700, true)) {
			return error(-1, '提取文件失败: 权限不足.');
		}
	}


	
	if (!$limit) {
		if ($type == 'images') {
			$limit = $_W['setting']['upload']['image']['limit'] * 1024;
		} else {
			$limit = $_W['setting']['upload']['audio']['limit'] * 1024;
		}
	} else {
		$limit = $limit * 1024;
	}
	if (intval($resp['headers']['Content-Length']) > $limit) {
		return error(-1, '上传的媒体文件过大(' . sizecount($resp['headers']['Content-Length']) . ' > ' . sizecount($limit));
	}
	$filename = file_random_name(ATTACHMENT_ROOT . $path, $ext);
	$pathname = $path . $filename;
	$fullname = ATTACHMENT_ROOT . $pathname;
	if (file_put_contents($fullname, $resp['content']) == false) {
		return error(-1, '提取失败.');
	}

	return $pathname;
}

function file_is_image($url) {
	if (!parse_path($url)) {
		return false;
	}
	$pathinfo = pathinfo($url);
	$extension = strtolower($pathinfo['extension']);

	return !empty($extension) && in_array($extension, array('jpg', 'jpeg', 'gif', 'png'));
}


function file_image_quality($src, $to_path, $ext) {
	load()->classs('image');
	global $_W;
		$quality = intval($_W['setting']['upload']['image']['zip_percentage']);
	if ($quality <= 0 || $quality >= 100) {
		return;
	}

		if (filesize($src) / 1024 > 5120) {
		return;
	}

	$result = Image::create($src, $ext)->saveTo($to_path, $quality);
	return $result;
}
