<?php

/**
 *--------------------------------------
 * 框架函数库
 *--------------------------------------
 * @project		: pfa
 * @author		: cblee
 * @created		: 2012-9-23
 * @copyright	: (c)2012 AsThis
 *--------------------------------------
 */

if(!defined('PFA_PATH')) exit();

/* 实例化控制器 */
function A($name = '')
{
	static $_ctrlr = array();
	if(empty($name))
	{
		return new Ctrlr;
	}
	if(isset($_ctrlr[$name]))
	{
		return $_ctrlr[$name];
	}
	$OriClassName = $name;
	if(strpos($name, C('APP.GROUP_DEPR')))
	{
		$array = explode(C('APP.GROUP_DEPR'), $name);
		$name = array_pop($array);
		$className = $name.'Ctrlr';
		import(implode(C('APP.GROUP_DEPR'), $array).'.'.$className, LIB_CTRLR_PATH);
	}
	else
	{
		$className = $name.'Ctrlr';
		import($className, LIB_CTRLR_PATH);
	}
	if(class_exists($className, false))
	{
		$ctrlr = new $className();
		$_ctrlr[$OriClassName] = $ctrlr;
		return $ctrlr;
	}
	else
	{
		return false;
	}
}

/* 实例化Modl */
function M($name = '')
{
	static $_modl = array();
	if(empty($name))
	{
		return new Modl;
	}
	if(isset($_modl[$name]))
	{
		return $_modl[$name];
	}
	$OriClassName = $name;
	$className = $name.'Modl';
	if(class_exists($className))
	{
		$modl = new $className();
	}
	else
	{
		$modl = new Modl($name);
	}
	$_modl[$OriClassName] = $modl;
	return $modl;
}

/* 简单类型数据(字符串,数组)快速文件数据读取和保存 */
function F($name, $value = '', $path = DATA_PATH)
{
	static $_cache = array();
	$path = rtrim($path, "/\\").D_S;
	$filename = $path.$name.'.php';
	if('' !== $value)
	{
		if(is_null($value))
		{
			if(is_file($filename))
			{
				@unlink($filename); /* 删除缓存 */
			}
			return;
		}
		else
		{
			$dir = dirname($filename); /* 缓存数据 */
			if(!is_dir($dir))
			{
				mk_dir($dir); /* 目录不存在则创建 */
			}
			$_cache[$name] = $value;
			return file_put_contents($filename, strip_whitespace("<?php\r\nreturn ".var_export($value, true).";\r\n?>"));
		}
	}
	if(isset($_cache[$name]))
	{
		return $_cache[$name];
	}
	if(is_file($filename)) /* 获取缓存数据 */
	{
		$value = include $filename;
		$_cache[$name] = $value;
		return $value;
	}
	return false;
}

/* 全局缓存设置和读取 */
function S($name, $value = '', $expire = null, $options = null)
{
	$type = isset($options['cacheType']) ? $options['cacheType'] : '';
	static $_cache = array();
	$cache = Cache::connect($options);
	if('' !== $value)
	{
		if(is_null($value)) /* 删除缓存 */
		{
			$result = $cache->del($name);
			if($result)
			{
				unset($_cache[$type.'_'.$name]);
			}
			return $result;
		}
		else /* 缓存数据 */
		{
			$cache->set($name, $value, $expire);
			$_cache[$type.'_'.$name] = $value;
		}
		return;
	}
	if(isset($_cache[$type.'_'.$name]))
	{
		return $_cache[$type.'_'.$name];
	}
	/* 获取缓存数据 */
	$value = $cache->get($name);
	$_cache[$type.'_'.$name] = $value;
	return $value;
}

/* 设置和获取计数 */
function N($key, $step = 0)
{
	static $_num = array();
	if(!isset($_num[$key]))
	{
		$_num[$key] = 0;
	}
	if(empty($step))
	{
		return $_num[$key];
	}
	else
	{
		$_num[$key] = $_num[$key] + (int)$step;
	}
}

/* 获取,定义配置 */
function C($name = null, $value = null)
{
	return _SG($name, $value, 'config');
}

/* 获取,定义语言 */
function L($name = null, $value = null)
{
	return _SG($name, $value, 'language');
}

/* 获取,定义*/
function _SG($key = null, $value = null, $name = 'default')
{
	static $_temp = array();
	if(!isset($_temp[$name] ))
	{
		$_temp[$name] = array();
	}
	/* 无参数时获取所有 */
	if(empty($key))
	{
		return $_temp[$name];
	}
	/* 获取或定义 */
	if(is_string($key))
	{
		if(!strpos($key, '.'))
		{
			if(is_null($value))
			{
				return isset($_temp[$name][$key]) ? $_temp[$name][$key] : $key;
			}
			$_temp[$name][$key] = $value;
			return;
		}
		/* 二维数组 */
		$key = explode('.', $key);
		if(is_null($value))
		{
			return isset($_temp[$name][$key[0]][$key[1]]) ? $_temp[$name][$key[0]][$key[1]] : $key[0].'.'.$key[1];
		}
		$_temp[$name][$key[0]][$key[1]] = $value;
		return;
	}
	/* 批量定义 */
	if(is_array($key))
	{
		foreach($key as $k => $v)
		{
			if(is_array($v))
			{
				if(isset($_temp[$name][$k]))
				{
					$_temp[$name][$k] = array_merge($_temp[$name][$k], $v);
				}
				else
				{
					$_temp[$name][$k] = $v;
				}
			}
			else
			{
				$_temp[$name][$k] = $v;
			}
		}
	}
	return;
}

/* 检查时间间隔 记录时间I($name), 检查间隔I($name, $inerval) */
function I($name = 'interaction', $interval = '')
{
	/* interval为空, 记录当前时间 */
	if(empty($interval))
	{
		return ASession::set($name, time());
	}

	/* 检查时间间隔 */
	if(!ASession::get($name))
	{
		ASession::set($name, time());
	}
	elseif((time() - ASession::get($name)) < $interval)
	{
		return false;
	}
	return true;
}

/* 格式化显示变量内容 */
function P()
{
	$args = func_get_args(); /* 获取多个参数 */
	if(count($args) < 1)
	{
		echo "<font color='red'>P() must have at least one arg!</font>";
		return;
	}
	echo "<div><pre>\r\n";
	foreach($args as $arg)
	{
		if(is_array($arg))
		{
			print_r($arg);
		}
		elseif(is_string($arg))
		{
			echo $arg."<br />\r\n";
		}
		else
		{
			var_dump($arg);
		}
	}
	echo "</pre></div>\r\n";
}

/* 取得对象实例 */
function get_instance($class, $classArgs = array(), $method = '', $methodArgs = array())
{
	static $_instance = array();
	$identify = empty($classArgs) ? $class : $class.get_guid_string($classArgs);
	if(!isset($_instance[$identify]))
	{
		if(class_exists($class))
		{
			$o = new $class($classArgs);
			if(method_exists($o, $method))
			{
				if(!empty($args))
				{
					$_instance[$identify] = call_user_func_array(array(&$o, $method), $methodArgs);
				}
				else
				{
					$_instance[$identify] = $o->$method();
				}
			}
			else
			{
				if('' == $method)
				{
					$_instance[$identify] = $o;
				}
				else
				{
					halt(L('_METHOD_NOT_EXIST_').' : '.$method);
				}
			}
		}
		else
		{
			halt(L('_CLASS_NOT_EXIST_').' : '.$class);
		}
	}
	return $_instance[$identify];
}
/* 自动加载类 */
function __autoload($classname)
{
	/* 加载应用的Ctrlr类和Modl类 */
	if('Modl' == substr($classname, -4))
	{
		$classfile = LIB_MODL_PATH.D_S.$classname.'.class.php';
		require_cache($classfile);
	}
	elseif('Ctrlr' == substr($classname, -5))
	{
		if(defined('GROUP_NAME'))
		{
			$classfile = LIB_CTRLR_PATH.D_S.GROUP_NAME.D_S.$classname.'.class.php';
			require_cache($classfile);
		}
		if(!file_exists($classfile))
		{
			$classfile = LIB_CTRLR_PATH.D_S.$classname.'.class.php';
			require_cache($classfile);
		}
	}
	else
	{
		$include_path = get_include_path();
		$include_path .= P_S.PFA_EXT_PATH; /* PFA扩展类库目录 */
		$include_path .= P_S.PFA_VENDER_PATH; /* PFA第三方类库目录 */
		/* 根据自动加载路径设置尝试搜索 */
		if(C('APP.AUTOLOAD_PATH'))
		{
			$paths = str_replace(',', P_S, C('APP.AUTOLOAD_PATH'));
			$include_path .= P_S.$paths;
		}
		set_include_path($include_path);
		import($classname);
	}
	return;
}

/* 导入函数库文件(文件名中包含'.'时用'#'替换) */
function load($name, $baseUrl = '', $ext = '.php')
{
	$name = str_replace(array('.', '#'), array('/', '.'), $name);
	if(empty($baseUrl))
	{
		$baseUrl = LIB_COMM_PATH; /* 加载应用函数库目录 */
	}
	$baseUrl = rtrim($baseUrl, '/\\').D_S;
	return require_cache($baseUrl.$name.$ext);
}

/* 导入类文件(文件名中包含'.'时用'#'替换) ext和vendor目录自动加载 */
function import($class, $baseUrl = '', $ext='.class.php')
{
	static $_file = array();
	static $_class = array();
	$class = str_replace(array('.', '#'), array('/', '.'), $class);
	if(isset($_file[$class.$baseUrl]))
	{
		return true;
	}
	else
	{
		$_file[$class.$baseUrl] = true;
	}
	if(empty($baseUrl)) /* 默认导入set_include_path路径中的文件 */
	{
		$include_path = get_include_path();
		$paths = explode(P_S, $include_path);
		foreach($paths as $path)
		{
			$classfile = $path.D_S.$class.$ext;
			/* 区分文件名大小写 */
			if(basename(realpath($classfile)) == basename($classfile))
			{
				return require_cache($classfile);
			}
		}
	}
	if(substr($baseUrl, -1) != '/')
	{
		$baseUrl .= '/';
	}
	$classfile = $baseUrl.$class.$ext;
	if($ext == '.class.php' && is_file($classfile))
	{
		/* 类冲突检测 */
		$class = basename($classfile, $ext);
		if(isset($_class[$class]))
		{
			halt(L('_CLASS_CONFLICT_').' : '.$_class[$class].' '.$classfile);
		}
		$_class[$class] = $classfile;
	}
	return require_cache($classfile);
}

/* 从各类型变量生成唯一标识号 */
function get_guid_string($mix)
{
	if(is_object($mix) && function_exists('spl_object_hash'))
	{
		return spl_object_hash($mix);
	}
	elseif(is_resource($mix))
	{
		$mix = get_resource_type($mix).strval($mix);
	}
	else
	{
		$mix = serialize($mix);
	}
	return md5($mix);
}

/* 命名风格转换 0:AaaBbb -> aaa_bbb, 1:aaa_bbb -> AaaBbb */
function parse_name($name, $type = 0)
{
	if($type)
	{
		return ucfirst(preg_replace("/_([a-zA-Z])/e", "strtoupper('\\1')", $name));
	}
	else
	{
		$name = preg_replace("/[A-Z]/", "_\\0", $name);
		return strtolower(trim($name, "_"));
	}
}

/* 优化require_once */
function require_cache($filename)
{
	static $_importFiles = array();
	$filename = realpath($filename);
	if(!isset($_importFiles[$filename]) && file_exists($filename))
	{
		return $_importFiles[$filename] = require $filename;
	}
}

/* 目录是否可写 */
function dir_writable($dir)
{
	if(!is_dir($dir))
	{
		mk_dir($dir, 0777);
	}
	if(is_dir($dir))
	{
		if($fp = @fopen("$dir/test.txt", 'w'))
		{
			@fclose($fp);
			@unlink(realpath("$dir/test.txt"));
			return true;
		}
	}
	return false;
}

/* 创建目录(尝试检测上级目录) */
function mk_dir($path, $mode = 0777)
{
	//$folder_path = array(strstr($path, '.') ? dirname($path) : $path);
	$folder_path = array($path);

	while(!@is_dir(dirname(end($folder_path)))
		&& dirname(end($folder_path)) != '/'
		&& dirname(end($folder_path)) != '.'
		&& dirname(end($folder_path)) != '')
	{
		array_push($folder_path, dirname(end($folder_path)));
	}

	while($parent_folder_path = array_pop($folder_path))
	{
		if(!@mkdir($parent_folder_path, $mode))
		{
			return false;
		}
	}
	return true;
}

/* 批量创建目录 */
function mkdirs($dirs, $mode = 0777)
{
	foreach($dirs as $dir)
	{
		if(!is_dir($dir))
		{
			mk_dir($dir, $mode);
		}
	}
}

/* 删除目录中的文件 $self:是否删除目录 */
function clear_dir($dir, $sub = false, $self = false)
{
	if(is_dir($dir) == false)
	{
		exit("The Directory Is Not Exist!");
	}
	$handle = opendir($dir);
	while(($file = readdir($handle)) !== false)
	{
		if($file != "." && $file != "..")
		{
			(is_dir("$dir/$file") && $sub) ? clear_dir("$dir/$file", $sub, $self) : @unlink(realpath("$dir/$file"));
		}
	}
	if(readdir($handle) == false)
	{
		closedir($handle);
		if($self)
		{
			@rmdir($dir);
		}
	}
}

/* 错误终止输出 */
function halt($error = '')
{
	if(IS_CLI)
	{
		exit($error);
	}
	if(C('DEBUG.SWITCH'))
	{
		if(!is_array($error))
		{
			$e = array();
			$traceInfo = '';
			$trace = debug_backtrace();
			$e['message'] = $error;
			$e['file'] = $trace[0]['file'];
			$e['class'] = isset($trace[0]['class']) ? $trace[0]['class'] : '';
			$e['function'] = isset($trace[0]['function']) ? $trace[0]['function'] : '';
			$e['line'] = $trace[0]['line'];
			$time = date('c');
			foreach($trace as $t)
			{
				$traceInfo .= '['.$time.'] '.$t['file'].' ('.$t['line'].') ';
				$traceInfo .= isset($t['class']) ? $t['class'] : '';
				$traceInfo .= isset($t['type']) ? $t['type'] : '';
				$traceInfo .= $t['function'].'('.array_to_string($t['args']);
				$traceInfo .=")<br/>";
			}
			$e['trace'] = $traceInfo;
		}
		else
		{
			$e = $error;
		}

		if(ob_get_length())
		{
			ob_clean();
		}
		include C('TPL.ERR_DEBUG');
		exit();
	}
	else
	{
		if(file_exists(C('TPL.ERR')))
		{
			if(ob_get_length())
			{
				ob_clean();
			}
			include C('TPL.ERR');
			exit();
		}
		else
		{
			exit($error);
		}
	}
}

/* URL重定向 */
function redirect($url, $time = 0, $msg = '')
{
	/* 多行URL地址支持 */
	$url = str_replace(array("\n", "\r"), '', $url);

	if(!headers_sent())
	{
		if(0 === $time)
		{
			header("Location: ".$url);
		}
		else
		{
			header("refresh: {$time}; url = {$url}");
			echo($msg);
		}
		exit();
	}
	else
	{
		$str = "<meta http-equiv='Refresh' content='{$time}; URL={$url}'>";
		if(0 != $time)
		{
			$str .= $msg;
		}
		exit($str);
	}
}

/* 数组转为字符串 $level:解析深度 */
function array_to_string($array, $glue = ', ', $level = 1)
{
	if(!is_array($array) || empty($array))
	{
		return '';
	}
	$string = '';
	foreach($array as $k => $v)
	{
		if(0 != $level)
		{
			if(is_array($v))
			{
				$string .= 'array(';
				$string .= array_to_string($v, $glue, $level - 1).$glue;
				$string = rtrim($string, $glue).')'.$glue;
			}
			else
			{
				$string .= $v.$glue;
			}
		}
	}
	$string = rtrim($string, $glue);
	return $string;
}

/* 去除代码中的空白和注释 */
function strip_whitespace($content)
{
	$stripStr = '';

	/* 分析php源码 */
	$tokens = token_get_all($content);
	$last_space = false;
	for($i = 0, $j = count($tokens); $i < $j; $i++)
	{
		if(is_string($tokens[$i]))
		{
			$last_space = false;
			$stripStr .= $tokens[$i];
		}
		else
		{
			switch($tokens[$i][0])
			{
				/* 过滤各种PHP注释 */
				case T_COMMENT:
				case T_DOC_COMMENT:
					break;
				/* 过滤多个空格 */
				case T_WHITESPACE:
					if(!$last_space)
					{
						$stripStr .= ' ';
						$last_space = true;
					}
					break;
				case T_START_HEREDOC:
					$stripStr .= "<<<PFA\r\n";
					break;
				case T_END_HEREDOC:
					$stripStr .= "PFA;\r\n";
					for($k = $i+1; $k < $j; $k++)
					{
						if(is_string($tokens[$k]) && $tokens[$k] == ";")
						{
							$i = $k;
							break;
						}
						else if($tokens[$k][0] == T_CLOSE_TAG)
						{
							break;
						}
					}
					break;
				default:
					$last_space = false;
					$stripStr .= $tokens[$i][1];
			}
		}
	}
	return $stripStr;
}

/* 字节格式化为 B KB MB GB TB */
function byte_format($size, $dec=2)
{
	$a = array("B", "KB", "MB", "GB", "TB", "PB");
	$pos = 0;
	while($size >= 1024)
	{
		$size /= 1024;
		$pos++;
	}
	return round($size, $dec)." ".$a[$pos];
}

/* 人性化时间格式 */
function get_dateStr($dateline)
{
	$timeDif = intval(time() - $dateline);
	$now = getdate();
	$todayPassTime = $now['seconds'] + $now['minutes'] * 60 + $now['hours'] * 60 * 60;

	if($timeDif < 0)
	{
		return L('_IN_THE_FUTURE_');
	}
	elseif($timeDif < 60)
	{
		$timeDif = $timeDif == 0 ? 1 : $timeDif;
		return $timeDif.L('_SECOND_AGO_');
	}
	elseif($timeDif < 3600)
	{
		$timeDif = intval($timeDif / 60);
		return $timeDif.L('_MINUTE_AGO_');
	}
	elseif($timeDif < $todayPassTime)
	{
		$timeDif = intval($timeDif / 3600);
		return $timeDif.L('_HOUR_AGO_');
	}
	elseif($timeDif < $todayPassTime + 3600 * 24)
	{
		return L('_YESTERDAY_').date(' H:i:s', $dateline);
	}
	elseif($timeDif < 3600 * 24 * 7)
	{
		$timeDif = intval($timeDif / 3600 / 24);
		return $timeDif.L('_DAY_AGO_');
	}
	return date('Y-m-d H:i:s', $dateline);
}

/* 删除数组空白 */
function trim_array($a = array(), $charList = '')
{
	if(0 == strlen($charList))
	{
		foreach($a as $k => $v)
		{
			$a[$k] = trim($v);
		}
	}
	else
	{
		foreach($a as $k => $v)
		{
			$a[$k] = trim($v, $charList);
		}
	}
	return $a;
}

//[RUNTIME]
/* 编译文件 */
function compile($filename)
{
	$content = file_get_contents($filename);
	/* 替换预编译指令 */
	$content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content);
	$content = substr(trim($content), 5);
	if('?>' == substr($content, -2))
	{
		$content = substr($content, 0, -2);
	}
	return $content;
}

/* 根据数组生成常量定义 */
function array_define($array)
{
	$content = '';
	foreach($array as $key => $val)
	{
		$key = strtoupper($key);
		$content .= 'if(!defined(\''.$key.'\')) ';
		if(is_int($val) || is_float($val))
		{
			$content .= "define('".$key."',".$val. ");";
		}
		elseif(is_bool($val))
		{
			$val = ($val) ? 'true' : 'false';
			$content .= "define('".$key."',".$val.");";
		}
		elseif(is_string($val))
		{
			$content .= "define('".$key."','".addslashes($val)."');";
		}
	}
	return $content;
}
//[/RUNTIME]

?>