<?php
/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
--	Common Functions
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */

/*
 * 返回系统配置
*/
function funcSystemConfig($params){
	global $configs;

	return $configs;
}

/* -- -- -- -- -- -- -- -- -- -- -- -- -- 数据库公共操作 -- -- -- -- -- -- -- -- -- -- -- -- -- */
/*
 * 基于模式连接数据库并返回连接对象
 * 返回 $db = array('object' => '连接对象', 'function' => '方法集')
*/
function connectDB($mode = "MySQLi"){
	global $configs;

	$conf = $configs['database'][$mode];

	$db = $conf['function']['Connect']($conf);

	return $db;
}

/* $conn = 数据库连接对象 */
function doSQL($sql, $conn = null){
	global $connDB;

	if(is_null($conn))$conn = $connDB;

	try{	
		return $conn['function']['Select']($conn['object'], $sql);
	}catch(Exception $e){
		return array();
	}
}

/* $conn = 数据库连接对象 */
function doPage($sql, $wheres, $pagecount = 50, $conn = null){
	global $connDB;

	if(is_null($conn))$conn = $connDB;

	try{	
		$pageSQL  = "select COUNT(*) as counts, CEILING(COUNT(*)/" . $pagecount . ") as pages from (" . $sql . ") pagedata ";
		$pageSQL .= ($wheres) ? ("where" . $wheres) : "";
		$result = $conn['function']['Select']($conn['object'], $pageSQL);
		return ($result) ? $result[0] : array();
	}catch(Exception $e){
		return array();
	}
}

/*
 * 分页公共语句
 * $params = array('pageno' => '页码', 'pagecount' => '每页数据', 'limit' => '数据量')
*/
function doPageSQL($params){
	$limits = "";
	if(isset($params['pageno'])){		
		if(!$params['pageno'] || $params['pageno'] == 1){
			$limits = " limit " . $params['pagecount'];
		}else{
			$limits = " limit " . ($params['pageno'] - 1) * $params['pagecount'] . ", " . $params['pagecount'];
		}
	}else{		
		if(isset($params['limit'])){
			$limits = " limit " . $params['limit'];
		}		
	}
	return $limits;
}

/* 
 * 组合SQL语句
 * $data => 数据体, $params = array('mode' => 'insert|update', 'table' => '表名', 'wheres' => '条件字符串') 
*/
function executeSQL($data, $params){
	global $connDB;

	if($params['mode'] == "insert"){
		$fields = "";
		$values = "";

		foreach($data as $key => $val){
			$fields .= ($fields == "") ? "" : ", ";
			$fields .= $key;

			$values .= ($values == "") ? "" : ", ";
			//$values .= (is_numeric($val)) ? $val : ("'" . $val . "'");
			$values .= ("'" . $val . "'");			
		}
		$sql = "insert into " . $params['table'] . "(" . $fields . ") values(" . $values . ")";
	}elseif($params['mode'] == "update"){
		$upds = "";
		foreach($data as $key => $val){
			$upds .= ($upds == "") ? "" : ", ";
			$upds .= $key . " = ";
			$upds .= (is_numeric($val)) ? $val : ("'" . $val . "'");
		}
		$sql = "update " . $params['table'] . " set " . $upds;
		if($params['where'])$sql .= " where " . $params['where'];
	}

	return $sql;
}

/*
 * 执行SQL语句
 * 
*/
function execSQL($sql, $func = null, $conn = null){
	global $connDB;

	if(is_null($conn))$conn = $connDB;

	if($func == "insert"){
		return $conn['function']['Insert']($conn['object'], $sql);
	}elseif($func == "insertid"){
		return $conn['function']['InsertId']($conn['object'], $sql);
	}elseif($func == "update"){
		return $conn['function']['Update']($conn['object'], $sql);
	}elseif($func == "delete"){
		return $conn['function']['Delete']($conn['object'], $sql);
	}else{
		return $conn['function']['Query']($conn['object'], $sql);
	}
}

/*
 * 基于参照格式化查询数据
 * $params = array('data' => 'rs结果集', 'datafield' => '需要格式化的字段', 'datatimes' => '需要格式化的时间戳字段')
*/
function funcFormatResultData($params){
	global $configs;

	$result = array();

	$fieldArray = explode(",", $params['datafield']);
	$timesArray = explode(",", $params['datatimes']);

	for($i = 0; $i < count($params['data']); $i++){
		$result[$i] = $params['data'][$i];
		if(count($fieldArray)){
		    for($keyField = 0; $keyField < count($fieldArray); $keyField++){
		        if($fieldArray[$keyField] != ''){
		            $result[$i][$fieldArray[$keyField] . '_format'] = $configs['refer']['refer_' . $fieldArray[$keyField]][$params['data'][$i][$fieldArray[$keyField]]];
		        }
		    }		    
		}
		if(count($timesArray)){
		    for($keyTimes = 0; $keyTimes < count($timesArray); $keyTimes++){
		        if($timesArray[$keyTimes]){
		            $result[$i][$timesArray[$keyTimes] . '_format'] = date("Y-m-d H:i:s", $params['data'][$i][$timesArray[$keyTimes]]);
		        }
		    }		    
		}
	}
	return $result;
}


/*
 * 自动加载文件 
 * $params = array(path => '文件夹路径', method => 'require_once|include_once')
*/
function funcComAutoLoad($params){
	try{
		if(is_file($params['path'])){
			funcComLoadExec($params['path'], $params['method']); //单文件加载
		}else{
			$folder = scandir($params['path']);

			foreach($folder as $incfile){
				if($incfile != '.' && $incfile != '..'){			
					if(!is_dir($params['path'] . '/' . $incfile)){
						funcComLoadExec($params['path'] . '/' . $incfile, $params['method']);
					}
				}
			}
		}
		return true;
	}catch(Exception $Err){
		return $E->getMessage();
	}
}

function funcComLoadExec($path, $method){
	if($method == "include_once"){
		include_once($path);
	}
	if($method == "include"){
		include($path);
	}
	if($method == "require_once"){
		require_once($path);
	}
	if($method == "require"){
		require($path);
	}
}

/*
 * CURL 执行
 * $params = array(url => '请求地址', json => false|true, data => '报文数据')
*/
function funcComCurl($params){
	if(empty($params['url']))return false;
	
	$CURL = curl_init();

	curl_setopt($CURL, CURLOPT_URL, $params['url']);

	if($params['json']){
		curl_setopt($CURL, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen(json_encode($params['data'], JSON_UNESCAPED_UNICODE))));
	}

	if(!empty($params['data'])){
		curl_setopt($CURL, CURLOPT_POST, 1);
		curl_setopt($CURL, CURLOPT_POSTFIELDS, $params['data']);
	}

	curl_setopt($CURL, CURLOPT_TIMEOUT, 30);curl_setopt($CURL, CURLOPT_SSL_VERIFYPEER, FALSE);
	curl_setopt($CURL, CURLOPT_SSL_VERIFYHOST, FALSE);curl_setopt($CURL, CURLOPT_HEADER, FALSE);curl_setopt($CURL, CURLOPT_RETURNTRANSFER, TRUE);
	
	$response = curl_exec($CURL);
	
	curl_close($CURL);

	return (!$response) ? false : $response;	
}

/*
 * 转UTF8
*/
function funcComArrayTranUtf8($res){
	return ($res != "" && !is_null($res) && !is_object($res)) ? iconv('GBK', 'UTF-8', $res) : '';
}

/*
 * 转GBK
*/
function funcComArrayTranGBK($res){
	return ($res != "" && !is_null($res) && !is_object($res)) ? iconv("UTF-8", "GBK", $res) : '';
}

/*
 * 随机函数
 * returnRandom('rand', array('num' => 12))
*/
function funcComRandom($mode, $params = null){
	global $configs;

	$randMode = array(
		'verify' => '0123456789',
		'rand'   => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
		'random' => 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
	);

	$num = ($params['num']) ? $params['num'] : 6; 

	$key = "";
	for($j = 0; $j < $num; $j++){
		$key .= $randMode[$mode][rand(0, strlen($randMode[$mode])-1)];
	}
	
	return $key;
}

/*
 * 数组转http字符串
 * array => http& 
*/
function funcComArrayToHttp($paraMap, $urlencode = false){
	$buff = "";
	//ksort($paraMap);
	foreach ($paraMap as $k => $v){
		if($urlencode){$v = urlencode($v);}
		$buff .= $k . "=" . $v . "&";
	}
	$reqPar;
	if (strlen($buff) > 0){$reqPar = substr($buff, 0, strlen($buff)-1);}
	return $reqPar;
}

/*
 * http字符串转数组
 * http& => array
*/
function funcComHttpToArray($params){
	$output = array();if($params){parse_str($params, $output);}return $output;
}

/*
 * 数组转XML
*/
function funcComArrayToXml($arr){
	$xml = "<xml>";
	foreach($arr as $key => $val){
		if(is_numeric($val)){
			$xml .= "<" . $key . ">" . $val . "</" . $key . ">"; 
		}else{
			$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";  
		}
	}
	$xml.= "</xml>";
	return $xml; 
}

/*
 * XML转数组
 * $xml => object
*/
function funcComXmlToArray($xml){		
	//将XML转为array        
	return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);		
}

/*
 * 获取SHA256加密
*/
function funcComSHA256($str){
	return bin2hex(hash('sha256', $str, true));
}

/*
 * 获取毫秒时间戳
*/
function funcComGetMillisecond(){
	list($microsecond , $time) = explode(' ', microtime()); //' '中间是一个空格
	return (float)sprintf('%.0f',(floatval($microsecond) + floatval($time)) * 1000);
}

/*
 * 获取请求客户端基础信息
*/
function funcComGetClientInfo($servers){
	$returns = array('ip' => '', 'port' => '', 'uri' => '', 'domain' => 0);

	$returns['ip']     = $servers['REMOTE_ADDR'];
	$returns['port']   = $servers['REMOTE_PORT'];
	$returns['uri']    = $servers['REQUEST_URI'];
	$returns['domain'] = ($servers['REMOTE_ADDR'] == $servers['SERVER_ADDR']) ? 1 : 0;

	return $returns;
}

/*
 * 获取文件后缀名
*/
function funcComGetFileExt($filename){
	$arrays = explode(".", $filename);
	return (count($arrays) >= 1) ? $arrays[count($arrays) - 1] : '';
}

/*
 * 生成二维码
 * $params = array('errorCorrectionLevel' => 'M(默认)', 'matrixPointSize' => '5(默认)', 'filename' => '生成文件名(默认随机串)', 'filepath' => '生成路径', 'lib' => '类库路径(默认)', 'data' => '封装数据')
*/
function funcComCreateQrCode($params){
	global $configs;

	$returns = array('success' => true, 'errorcode' => '200', 'msg' => $configs['errors']['200'], 'data' => array());

	$lib = (isset($params['lib'])) ? $params['lib'] : 'lib/php-phpqrcode/phpqrcode.php';

	require_once($lib);

	$errorCorrectionLevel = (isset($params['errorCorrectionLevel'])) ? $params['errorCorrectionLevel'] : 'M';    //容错级别
	$matrixPointSize      = (isset($params['matrixPointSize'])) ? $params['matrixPointSize'] : 5;

	$filename = (isset($params['filename'])) ? $params['filename'] : (time() . funcComRandom('rand', array('num' => 3)));

	$filepath = (isset($params['filepath'])) ? $params['filepath'] : $configs['qrcode']['path'];

	QRcode::png($params['data'], $filepath . $filename . ".png", $errorCorrectionLevel, $matrixPointSize, 2);

	$returns['data'] = array('filepath' => $filepath . $filename . ".png", 'filename' => $filename);

	return  $returns;
}

/*
 * 上传文件公共函数
*/
function funcComFileUpload($file){
	global $configs;

	$returns = array('success' => false, 'errorcode' => '403', 'data' => array());

	$todo = true;

	if(isset($file['params'])){
		/* 验证 */
		foreach($file['params'] as $key => $val){
			if($key == "ext-access"){
				if(!in_array(funcComGetFileExt($file['file']['name']), $val)){
					$todo = false;
					break;
				}
			}
			if($key == "limit-access"){
				if((int)$file['file']['size'] < $val[0] || (int)$file['file']['size'] > $val[1]){
					$todo = false;
					break;
				}
			}
			if($key == "check-ext"){
				if(!in_array(funcComGetFileExt($file['file']['name']), $configs['upload']['exts'])){
					echo "222";
					$todo = false;
					break;
				}
			}
			if($key == "check-limit"){
				if((int)$file['file']['size'] < $configs['upload']['limit'][0] || (int)$file['file']['size'] > $configs['upload']['limit'][1]){
					echo "111";
					$todo = false;
					break;
				}
			}
		}
	}

	if(isset($file['params']['folder']) && $file['params']['folder']){
		$file['params']['folder'] = $file['params']['folder'] . "/";
		
	}else{
		$file['params']['folder'] = "/";
	}

	if($todo){
		try{
			$obj = $file['file'];
			$returns['data']['file_filename'] = $obj['name'];
			$returns['data']['file_savename'] = "file-" . funcComGetMillisecond() . "." . funcComGetFileExt($obj['name']);

			if(move_uploaded_file($obj["tmp_name"], $configs['upload']['path'] . $file['params']['folder'] . $returns['data']['file_savename'])){
				$returns['data']['file_savepath'] = $configs['upload']['path'] . $file['params']['folder'];
				$returns['success'] = true;
				$returns['errorcode'] = "200";
			}else{
				$returns['msg'] = $configs['errors'][$returns['errorcode']] . " 保存文件错误";
			}			
		}catch(Exception $E){
			$returns['msg'] = $configs['errors'][$returns['errorcode']] . " 执行保存错误" . $E->getMessage();
		}
	}else{
		$returns['msg'] = $configs['errors'][$returns['errorcode']] . " 文件类型错误或超出大小限制";
	}

	return $returns;
}

/*
 * 日志
 * $params = array('log' => '日志内容', 'path' => '(默认文件)')
*/
function funcComLog($params){
	global $configs;

	if(isset($params['path'])){
		$filename = $params['path'];
	}else{
		$filepath = strftime("%Y%m%d", time());
		if(!file_exists($configs['log']['path'] . "/" . $filepath))mkdir($configs['log']['path'] . "/" . $filepath, 0755);
		$filename = $configs['log']['path'] . "/" . $filepath . "/" . strftime("%Y%m%d%H", time()) . ".log";
	}

	$file = fopen($filename, "a");
	flock($file, LOCK_EX);
	fwrite($file, date('Y-m-d H:i:s') . ":" . $params['log']. "\n\n");
	flock($file, LOCK_UN);
	
	fclose($file);
}

?>