<?php
class Func {
	public function getHash($key) {
		$key = md5($key);
		$key = str_split($key, 1);
		$key = array_unique($key);
		return implode ('', $key);
	}
	/**
	 * 脏文字过滤
	 *
	 * @access public
	 * @param  $str
	 * @return string
	 */
	public function fbword($str) {
		$fbword = explode(',', C('fbword'));
		foreach($fbword as $val) {
			if (!$val) continue;
			$v = explode('=', $val);
			$v[1] or $v[1] = '***';
			if (strpos($str, $v[0]) !== false) {
				$str = str_replace($v[0], $v[1], $str);
			}
		}
		return $str;
	}
	/**
	 * 分页
	 *
	 * @param intval $page 分页
	 * @param intval $totle 总数
	 * @param string $url 传入的地址(一般用于静态网页)
	 * @param string $firstUrl 首页地址(一般用于静态网页)
	 * @param intval $pageSize 每页记录数
	 * @param string $max 同一批次最大分页数
	 * @return str
	 */
	public function pages($page, $totle, $url = '', $firstUrl = '', $pageSize = 1, $max = 10) {
		$pagesStr = $pageSize == 1?'%FIRST% %PRE% %PAGENUM% %NEXT% %LAST% %GO%':'%TOTLE% %FIRST% %PRE% %PAGENUM% %NEXT% %LAST% %GO%';
		if (empty($url)) {
			$url = del_query_string('page');
			if ($url)$url .= '&';
			$url = SCRIPT_NAME . '?' . $url . 'page={page}';
		}
		$page = max(intval($page), 1);
		if ($pageSize < 1) {
			show_error(L('PAGE_SIZE_ERROR'));
		}
		$pages = ceil($totle / $pageSize);
		if ($pages <= 1) return false;
		$page = min($pages, $page);
		$first = $last = $go = '';
		$firstUrl or $firstUrl = str_replace('{page}', 1, $url);
		if ($max && $pages > $max) {
			$prenum = floor($max / 2);
			$nextnum = ceil($max / 2);
			if ($page < $prenum) {
				$start = 1;
				$end = $max;
			} elseif ($page + $nextnum > $pages) {
				$end = $pages;
				$start = $pages - $max + 1;
			} else {
				$start = $page - $prenum + 1;
				$end = $page + $nextnum;
			}
			$page > $prenum && $first = '<a href="' . $firstUrl . '">' . L('PAGE_FIRST') . '</a>';
			$page < $pages - $nextnum && $last = '<a href="' . str_replace('{page}', $pages, $url) . '">' . L('PAGE_LAST') . '</a>';
			$go = "<span class=\"pagesone\"><span>Pages: $page/$pages</span><input type=\"text\" size=\"3\" onkeydown=\"javascript: if(event.keyCode==13){var url='$url';var go=this.value;if(go>1)url=url.replace('{page}',go);else url='$firstUrl';location=url;return false;}\"><button onclick=\"javascript:var url='$url';var go=this.previousSibling.value;if(go>1)url=url.replace('{page}',go);else url='$firstUrl';location=url;return false;\">Go</button></span>";
		} else {
			$start = 1;
			$end = $pages;
		}
		if ($page > 1) {
			$preurl = $page > 2 ? str_replace('{page}', $page-1, $url) : $firstUrl;
			$pre = '<a href="' . $preurl . '">' . L('PAGE_PRE') . '</a>';
		} else $pre = '<span class="txt">' . L('PAGE_PRE') . '</span>';
		$pageNum = '';
		for($i = $start; $i <= $end; $i++) {
			if ($page == $i)$pageNum .= '<strong>' . $i . '</strong>';
			else {
				$theurl = $i > 1 ? str_replace('{page}', $i, $url) : $firstUrl;
				$pageNum .= "<a href=\"$theurl\">$i</a>";
			}
		}
		if ($page < $pages) {
			$next = '<a href="' . str_replace('{page}', $page + 1, $url) . '">' . L('PAGE_NEXT') . '</a>';
		} else $next = '<span class="txt">' . L('PAGE_NEXT') . '</span>';
		$totle = '<span class="txt">' . L('TOTLE') . $totle . '</span>';
		$search = array('%TOTLE%', '%FIRST%', '%PRE%', '%PAGENUM%', '%NEXT%', '%LAST%', '%GO%');
		$replace = array($totle, $first, $pre, $pageNum, $next, $last, $go);
		return str_replace($search, $replace, $pagesStr);
	}
	public function dheader($string, $replace = true, $http_response_code = 0) {
		$islocation = substr(strtolower(trim($string)), 0, 8) == 'location';
		if (defined('IN_MOBILE') && strpos($string, 'mobile') === false && $islocation) {
			if (strpos($string, '?') === false) {
				$string = $string . '?mobile=yes';
			} else {
				if (strpos($string, '#') === false) {
					$string = $string . '&mobile=yes';
				} else {
					$str_arr = explode('#', $string);
					$str_arr[0] = $str_arr[0] . '&mobile=yes';
					$string = implode('#', $str_arr);
				}
			}
		}
		$string = str_replace(array("\r", "\n"), array('', ''), $string);
		if (empty($http_response_code) || PHP_VERSION < '4.3') {
			@header($string, $replace);
		} else {
			@header($string, $replace, $http_response_code);
		}
		if ($islocation) {
			exit();
		}
	}
	// 防止XSS攻击
	public function removeXSS($val) {
		// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
		// this prevents some character re-spacing such as <java\0script>
		// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
		$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
		// straight replacements, the user should never need these since they're normal characters
		// this prevents like <IMG SRC=@avascript:alert('XSS')>
		$search = 'abcdefghijklmnopqrstuvwxyz';
		$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
		$search .= '1234567890!@#$%^&*()';
		$search .= '~`";:?+/={}[]-_|\'\\';
		for ($i = 0; $i < strlen($search); $i++) {
			// ;? matches the ;, which is optional
			// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
			// search for the hex values
			$val = preg_replace('/(&#[xX]0{0,8}' . dechex(ord($search[$i])) . ';?)/i', $search[$i], $val); // with a ;
			// 0{0,7} matches '0' zero to seven times
			$val = preg_replace('/(&#0{0,8}' . ord($search[$i]) . ';?)/', $search[$i], $val); // with a ;
		}
		// now the only remaining whitespace attacks are \t, \n, and \r
		$ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'base');
		$ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
		$ra = array_merge($ra1, $ra2);

		$found = true; // keep replacing as long as the previous round replaced something
		while ($found == true) {
			$val_before = $val;
			for ($i = 0; $i < sizeof($ra); $i++) {
				$pattern = '/';
				for ($j = 0; $j < strlen($ra[$i]); $j++) {
					if ($j > 0) {
						$pattern .= '(';
						$pattern .= '(&#[xX]0{0,8}([9ab]);)';
						$pattern .= '|';
						$pattern .= '|(&#0{0,8}([9|10|13]);)';
						$pattern .= ')*';
					}
					$pattern .= $ra[$i][$j];
				}
				$pattern .= '/i';
				$replacement = substr($ra[$i], 0, 2) . '<x>' . substr($ra[$i], 2); // add in <> to nerf the tag
				$val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
				if ($val_before == $val) {
					// no replacements were made, so exit the loop
					$found = false;
				}
			}
		}
		return $val;
	}
	// 与GBK兼容的中英文字符串长度统计
	public function utf8Strlen($str) {
		return (strlen($str) + mb_strlen($str, 'utf-8')) / 2;
	}
	// 取消HTML代码 用于输入处理，不能用于输出处理
	public function shtmlspecialchars($str) {
		if (is_array($str)) {
			foreach($str as $key => $val) {
				$str[$key] = shtmlspecialchars($val);
			}
		} else {
			$str = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
				str_replace(array('&', '"', '<', '>', '\''), array('&amp;', '&quot;', '&lt;', '&gt;', '&#039;'), $str));
		}
		return $str;
	}
	public function newIconv($in_charset, $out_charset, $str_or_arr) {
		if ($in_charset == $out_charset) return $str_or_arr;
		if (is_array($str_or_arr)) {
			foreach($str_or_arr as $k => $v) {
				$str_or_arr[$k] = self :: newIconv($in_charset, $out_charset, $v);
			}
		} else {
			$str_or_arr = iconv($in_charset, $out_charset, $str_or_arr);
		}
		return $str_or_arr;
	}
	public function newStripslashes($str_or_arr) {
		if (is_array($str_or_arr)) {
			foreach($str_or_arr as $k => $v) {
				$str_or_arr[$k] = self :: newStripslashes($v);
			}
		} else $str_or_arr = stripslashes($str_or_arr);
		return $str_or_arr;
	}
	/**
	 * 返回指定时间对应的 Unix 时间戳
	 *
	 * @access public
	 * @param  $str string
	 * @return int
	 */
	public function timeStamp($str) {
		if (empty($str))return 0;
		$tmp = explode(' ', $str);
		list($year, $month, $day) = explode('-', $tmp[0]);
		$tmp = isset($tmp[1])?explode(':', $tmp[1]):'';
		$hours = isset($tmp[0])?intval($tmp[0]):0;
		$minutes = isset($tmp[1])?intval($tmp[1]):0;
		$seconds = isset($tmp[2])?intval($tmp[2]):0;
		return mktime($hours, $minutes, $seconds, $month, $day, $year);
	}
	/**
	 * 在显示前补充目录
	 *
	 * @access public
	 * @param  $str string
	 * @param  $dir string 为空时,补充上传目录
	 * @return string
	 */
	public function fillDir($str, $dir = '') {
		if (!defined('IN_ADMIN')) {
			if ($str) {
				$dir or $dir = C('uploaddir', 0, 'attachment');
				$str = preg_replace("/([=|\(][\"|'| ]*)(" . $dir . "\/)/i", "\\1" . APP_URL . "\\2", $str);
			}
		}
		return $str;
	}
	// 过滤用于搜索的字符串
	public function filterSearch($str, $isFuzzy = 0) {
		if (!empty($str)) {
			$fh = array('.', ',', ';', ':', '?', '!', '*', '…', '-', '~', '(', ')', '{', '}', '</', '<', '/>', '>', '"', '\'', '\\', '。', '，', '；', '：', '？', '！', '＊', '……', '—', '～', '〔', '〕', '｛', '｝', '‘', '’', '“', '”');
			// 清除指定标点符号
			foreach($fh as $tmp) {
				$str = str_replace($tmp, ' ', $str);
			}
			$isFuzzy or $str = str_replace('%', ' ', $str); //非模糊查询删除 “%”
			$str = preg_replace("/[\s]+/", ' ', $str);
		}
		return $str;
	}
	// 替换
	public function replace($content, $old, $new = '') {
		if (substr($old, -5) == '(end)') {
			$old = substr($old, 0, -5);
			$pos = strrpos($content, $old);
			if ($pos) {
				$content = substr($content, 0, $pos) . $new;
			}
		} else {
			$old = preg_quote($old); //php自带正则转义
			$old = str_replace('\(\*\)', '(.*?)', $old); //转义自定义通配符
			$old = str_replace('/', '\/', $old); //转义斜杠
			$old = str_replace('"', '\"', $old); //转义双引号
			$old = preg_replace("/[\r\n]+/", '', $old); //转义回车换行
			$new = preg_replace('/\(\$([0-9]+)\)/', '\\\\\\1', $new);
			$content = preg_replace("/{$old}/is", $new, $content);
		}
		$tmp1 = substr($content, strrpos($content, '</'));
		$tmp1 = substr($tmp1, strpos($tmp1, '>') + 1);
		$tmp2 = str_replace('&nbsp;', '', $tmp1);
		$tmp2 = preg_replace("/[\s]+/", '', $tmp2);
		if ($tmp1 && trim(strip_tags($tmp2)) == '') {
			$content = substr($content, 0, - strlen($tmp1));
		}
		return $content;
	}
}
