<?php
/* * *********************************************************
 * [cml] (C)2012 - 3000 cml http://linhecheng.com
 * @Author  linhecheng<linhechengbush@live.com>
 * @Date: 13-6-26 上午11:23
 * @version  1.0 
 * cml框架公用函数库
 * *********************************************************** */

defined('CML_PATH') || exit();

/**
 * 友好的变量输出
 *
 * @param mixed $var 变量
 * @param int $getArgs 获取要打印的值
 * @return void|string
 */
function dump($var , $getArgs = 0)
{
	if($GLOBALS['APP_DEBUG']) {
		new dBug($var);	//deBug模式直接输出
	} else {
		static $args = array();
		if(($getArgs == 1)) return $args;
		$args[] = $var;//输出到浏览器控制台
	}
}

/**
 * 友好的变量输出并且终止程序
 *
 * @param mixed $var 变量
 * @return void|string
 */
function dd($var)
{
	dump($var);
	exit();
}


/**
 * 获取和设置配置参数 支持批量定义
 *
 * @param string|array $name 配置变量
 * @param mixed $value 配置值
 * @return mixed
 */
function C($name = null, $value = null)
{
	static $_config = array();
	// 无参数时获取所有
	if (empty($name)) {
		return $_config;
	}
	// 优先执行设置获取或赋值
	if (is_string($name)) {
		if (!strpos($name, '.')) {
			$name = strtolower($name);
			if (is_null($value)) return isset($_config[$name]) ? $_config[$name] : null;
			$_config[$name] = $value;
			return;
		}
		// 二维数组设置和获取支持
		$name = explode('.', $name);
		$name[0]   =  strtolower($name[0]);
		if (is_null($value)) return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : null;
		$_config[$name[0]][$name[1]] = $value;
		return;
	}
	// 批量设置
	if (is_array($name)){
		$_config = array_merge($_config, array_change_key_case($name));
		return;
	}
	return null; // 避免非法参数
}

/**
 * M函数用于实例化Model
 *
 * @param string $name Model名
 * @return object
 */
function M($name = 'Cml')
{
	static $_model = array(); //用于存储model实例

	$class = ucfirst($name).'Model';
	if(isset($_model[$name])) return $_model[$name];
	if(class_exists($class)) {
		$model = new $class();
		$_model[$name] = $model;
		return $model;
	} else {
		throw_exception(L('_FILE_NOT_FOUND_', null, $class));
	}
}

/**
 * 导入所需的类库
 *
 * @param string $name 类名
 * @param $dir 基础路径
 * @param string $ext 导入的文件扩展名 
 * @return boolen  io.file
 */
function import($name, $dir = CML_EXTEND_PATH, $ext = '.class.php')
{
	static $class = array(); //缓存类名
	if(!isset($class[$name])) {
		$file = $dir.DIR_SEP.strtr($name, '.', DIR_SEP).$ext; 
		if($GLOBALS['APP_DEBUG']) {
			require $file; 
			CmlDebug::addTipInfo(L('_CMLDEBUG_ADDTIP_CLASS_', null, $name), 1);//在debug中显示包含的类
		} else {
			$dir = RUNTIME_CACHE_PATH.DIR_SEP.'Libs'.DIR_SEP;
			//压缩文件 
			!is_dir($dir) && mkdir($dir, 0700, true);
			$runTimeFile = $dir.md5($file).'.php';
			!is_file($runTimeFile) && file_put_contents($runTimeFile, php_strip_whitespace($file));
			require $runTimeFile;
			$dir = $runTimeFile = null;
		}        
		$file = null;
		$class[$name] = 1;      
	}
}

/**
 * 判断是否为手机浏览器
 *
 * @return bool
 */
function isMobile()
{
	if($_GET['mobile'] === 'yes') {		
		setcookie('ismobile', 'yes', 3600);
		return true;				
	} else if($_GET['mobile'] === 'no') {
		setcookie('ismobile', 'no', 3600);
		return false;
	}

	$cookie = $_COOKIE('ismobile');		
	if($cookie === 'yes') {
		return true;
	} else if($cookie === 'no') {
		return false;
	} else {				
		$cookie = null;
		static $mobilebrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
				'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
				'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
				'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
				'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
				'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
				'benq', 'haier', '^lct', '320x320', '240x320', '176x220');
		foreach ($mobilebrowser_list as $val) {
			$result = strpos(strtolower($_SERVER['HTTP_USER_AGENT']), $val);
			if(false !== $result) {
				setcookie('ismobile', 'yes', 3600);
				return true;
			} 
		}	
		setcookie('ismobile', 'no', 3600);
		return false;
	}		
}

/**
 * 获取和设置语言定义(不区分大小写)
 * 获取值的时候可以动态传参转出语言值
 * 如：L('_CMLDEBUG_ADDTIP_CLASS_', null, 'CmlBase') 取出_CMLDEBUG_ADDTIP_CLASS_语言变量且将Cmlbase替换语言中的%s
 *
 * @param string|array $name 语言变量
 * @param string $value 语言值
 * @return mixed
 */
function L($name = null, $value = null)
{
	static $_lang = array();
	if (empty($name)) return false;	
	// 判断语言获取(或设置)
	if (is_string($name)) {
		$name = strtoupper($name);
		if (is_null($value)) {
			$replace = func_get_args();
			unset($replace[1]);
			$replace[0] = $_lang[$name];
			return isset($_lang[$name]) ? call_user_func_array('sprintf', array_values($replace)) : '';
		} else {
			$_lang[$name] = $value; // 语言定义
			return true;
		}
	}
	// 批量定义
	if (is_array($name)) $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER));
	return true;
}

/**
 * URL组装 支持不同URL模式
 *
 * @param string $url URL表达式，格式：'模块/控制器/操作'
 * @param string|array $vars 传入的参数，支持数组和字符串
 * @param string $suffix 伪静态后缀，默认为true表示获取配置值
 * @param int $echo 是否输出  1输出 0 return 
 * @return string
 * eg: U('Home/Blog/cate',array('cate_id'=>1,'status'=>1))
 */
function U($url = '',$vars = array(),$suffix = true, $echo = 1)
{
	// 解析URL
	empty($url) && throw_exception(L('_CML_ERROR_')); //'U方法参数出错'
	// URL组装
	$depr = C('URL_PATHINFO_DEPR');
	$url = explode('/', trim($url));
	if(count($url) === 3 && !C('APP_MODULE')) {
		throw_exception(L('_CML_ERROR_'));//U方法调用出错，系统并未未开启分模块
	}

	if(C('URL_MODEL') == 0) {
		if(count($url) === 3) {// Home/Index/index
			$return = $_SERVER['SCRIPT_NAME'].'?'.C('VAR_MODULE').'='.$url[0];
			array_shift($url);      
			$return .= '&'.C('VAR_CONTROLLER').'='.$url[0];
			array_shift($url);
			$return .= '&'.C('VAR_ACTION').'='.$url[0];
		} else {
			if(count($url) === 2) {// Index/index
				$return = $_SERVER['SCRIPT_NAME'].'?'.C('VAR_CONTROLLER').'='.$url[0];
				array_shift($url);   
			} else { //index
				$return = $_SERVER['SCRIPT_NAME'].'?'.C('VAR_CONTROLLER').'='.$_GET[C('VAR_CONTROLLER')];
			}
			empty($url) || $return .= '&'.C('VAR_ACTION').'='.$url[0];
			array_shift($url);               
		}       
		foreach($vars as $key => $val) {
			$return .= '&'.$key.'='.$val;
		}        
	} else {
		if(C('URL_MODEL') == 1) {
			if(count($url) === 3) { //Home/Index/index
				$return = $_SERVER['SCRIPT_NAME'].'/'.$url[0];   
				array_shift($url);
				$return .= $depr.$url[0];
				array_shift($url);
			} else {
				$add = $_SERVER['SCRIPT_NAME'].'/';

				if(count($url) == 2) { // Index/index
					$return = $add.$url[0];
					array_shift($url);
				} else { // index
					$return = $add.$_GET[C('VAR_CONTROLLER')];
				}
			}
		} else if(C('URL_MODEL') == 2) {
			if(count($url) === 3) { // Home/Index/index
				$return = '/'.$url[0];   
				array_shift($url);
				$return .= $depr.$url[0];
				array_shift($url);
			} else {
				if(count($url) == 2) { // Index/index
					$return = '/'.$url[0];
					array_shift($url);
				} else { // index
					$return = '/'.$_GET[C('VAR_CONTROLLER')];
				}                
			}
		} else if(C('URL_MODEL') == 3){
			if(count($url) === 3) { // Home/Index/index
				$return = $_SERVER['SCRIPT_NAME'].'?'.C('VAR_PATHINFO').'=/'.$url[0];
				array_shift($url);
				$return .= $depr.$url[0];
				array_shift($url);
			} else {
				$add = $_SERVER['SCRIPT_NAME'].'?'.C('VAR_PATHINFO').'=/';
				if(count($url) == 2) { // Index/index
					$return = $add.$url[0];
					array_shift($url);
				} else { // index
					$return = $add.$_GET[C('VAR_CONTROLLER')];
				}
			}
		}
		empty($url) || $return .= $depr.$url[0];
		array_shift($url);
		if(!empty($vars)) {
			foreach($vars as $key => $val) {
				$return .= $depr.$key.$depr.$val;
			}
		}
		$return .= ($suffix === true && C('URL_MODEL') == 2) ? C('URL_HTML_SUFFIX') : '';
	}  
	if($echo === 1) {echo $return;} else {return $return;}  
}

/**
 * 自定义异常处理
 *
 * @param string $msg 异常消息
 * @param integer $code 异常代码 默认为0
 * @return void
 */
function throw_exception($msg, $code = 0)
{
	throw new Exception($msg, $code);   
}

/**
 * 获取get post
 *
 * @param string $name 要获取的变量
 * @param int $type 1为get 2为post
 * @param bool $filter 是否开启过滤
 * @return mixed
 */
function getGp($name, $type = 1, $filter = true)
{
	if($type == 1) {
		if(isset($_GET[$name]) && $_GET[$name] !== '' ) return ($filter ? CmlSecure::htmlspecialchars($_GET[$name]) : $_GET[$name]);
	} else {
		if(isset($_POST[$name]) && $_POST[$name] !== '') return ($filter ? CmlSecure::htmlspecialchars($_POST[$name]) : $_POST[$name]);
	}
	return null;    
}

/**
 * 快速文件数据读取和保存 针对简单类型数据 字符串、数组
 *
 * @param string $name 缓存名称
 * @param mixed $value 缓存值
 * @param string $path 缓存路径
 * @return mixed
 */
function F($name, $value = '', $path = RUNTIME_DATA_PATH)
{
	static $_cache = array();
	$filename = $path . '/'. $name . '.php';
	if ('' !== $value) {
		if (is_null($value)) {
			// 删除缓存
			return false !== @unlink($filename);
		} else {
			// 缓存数据
			$dir = dirname($filename);
			// 目录不存在则创建			
			is_dir($dir) ||	mkdir($dir, 0700, true);
			$_cache[$name] = $value;
			return file_put_contents($filename, "<?php\treturn ".var_export($value, true).";?>");
		}
	}
	if (isset($_cache[$name])) return $_cache[$name];
		// 获取缓存数据
	if (is_file($filename)) {
		$value = require $filename;
		$_cache[$name] = $value;
	} else {
		$value = false;
	}
	return $value;
}

/**
 * 生成唯一id
 *
 * @return string
 */
function createUnique()
{
	$data = $_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].microtime(true).rand();
	return sha1($data);
}

/**
 * 显示404页面
 *
 * @param string $tpl 模板路径
 * @return void
 */
function show404Page($tpl = null)
{
	header('HTTP/1.1 404 Not Found');
	is_null($tpl) && $tpl = CML_PATH.DIR_SEP.'Views'.DIR_SEP.'404.tpl';
	is_file($tpl) && require $tpl;
	exit();
}

/**
 * 获取POST过来的二进制数据,与手机端交互
 *
 *@return binary
 */
function getBinaryData()
{
	if (isset($GLOBALS['HTTP_RAW_POST_DATA']) && !empty($GLOBALS['HTTP_RAW_POST_DATA'])) {
		$data = $GLOBALS['HTTP_RAW_POST_DATA'];
	} else {
		$data = file_get_contents('php://input');
	}
	return $data;
}