<?php

/**
 *--------------------------------------
 * string filter
 *--------------------------------------
 * @project		: pfa
 * @author		: cblee
 * @created		: 2012-11-23
 * @copyright	: (c)2012 AsThis
 *--------------------------------------
 */
defined('PFA_PATH') or exit('Access Denied');

class AFilter {
	public static function safeHtml($string, $allowTags = 'table|tbody|tfoot|th|tr|td|div|p|ul|ol|li|dl|dt|dd|strong|em|b|i|u|a|span|img|br|object|param|embed|sup|sub|h1|h2|h3|h4|h5|h6|h7|small|blockquote|hr') {
		if(!is_scalar($string)) {
			return '';
		}

		$string = str_replace('[', '&#091;', $string);
		$string = str_replace(']', '&#093;', $string);
		$string = str_replace('|', '&#124;', $string);
		/* br */
		$string = preg_replace('/<br(\s\/)?'.'>/i', '[br]', $string);
		$string = preg_replace('/(\[br\]\s*){1,}/i', '[br]', $string);

		/*
		while(preg_match('/(<[^><]+)(lang|on|action|background|codebase|dynsrc|lowsrc)[^><]+/i', $string, $mat)) {
			$string = str_replace($mat[0], $mat[1], $string);
		}
		while(preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i', $string, $mat)) {
			$string = str_replace($mat[0], $mat[1].$mat[3], $string);
		} */

		/* convert allowed html tags */
		while(preg_match('/<('.$allowTags.')>/i', $string, $mat)) {
			$string = str_replace($mat[0], str_replace(array('<', '>'), array('[', ']'), $mat[0]), $string);
		}
		while(preg_match('/<('.$allowTags.') [^><]*>/i', $string, $mat)) {
			$string = str_replace($mat[0], str_replace(array('<', '>'), array('[', ']'), $mat[0]), $string);
		}
		while(preg_match('/<\/('.$allowTags.')>/i', $string, $mat)) {
			$string = str_replace($mat[0], str_replace(array('<', '>'), array('[', ']'), $mat[0]), $string);
		}

		/* convert qoute */
		while(preg_match('/(\[[^\[\]]*=\s*)(\"|\')([^\2=\[\]]+)\2([^\[\]]*\])/i', $string, $mat)) {
			$string = str_replace($mat[0], $mat[1].'|'.$mat[3].'|'.$mat[4], $string);
		}
		/* convert empty property */
		$string = str_replace(array('\'\'', '""'), '||', $string);
		/* filter error single quotes */
		while(preg_match('/\[[^\[\]]*(\"|\')[^\[\]]*\]/i', $string, $mat)) {
			$string = str_replace($mat[0], str_replace($mat[1], '', $mat[0]), $string);
		}

		/* convert all other unlawful < > " */
		$string = str_replace('<', '&lt;', $string);
		$string = str_replace('>', '&gt;', $string);
		$string = str_replace('"', '&quot;', $string);

		$string = str_replace('[', '<', $string);
		$string = str_replace(']', '>', $string);
		$string = str_replace('|', '"', $string);
		return $string;
	}

	/* check word format */
	public static function is_word($string) {
		/* \W:[^A-Za-z0-9_] */
		return !empty($string) and is_string($string) and !preg_match("/\W+/", $string);
	}

	/* check userid format, [veriable] */
	public static function is_userid($string) {
		return !empty($string) and is_string($string) and preg_match("/^[a-zA-Z_][a-zA-Z0-9_]+$/", $string);
	}

	/* check username format, [chinese,number,letter,_] */
	public static function is_username($string) {
		return !empty($string) and is_string($string) and preg_match("/^[\x7f-\xff\w]+$/", $string);
	}

	/* check email format */
	public static function is_email($string) {
		return is_string($string) and (strlen($string) > 5) and preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $string);
	}

	/* check zip code format */
	public static function is_zipCode($string) {
		return is_string($string) and (strlen($string) == 6) and preg_match("/^[1-9]\d{5}$/", $string);
	}

	/* check phone format */
	public static function is_phone($string) {
		return is_string($string) and (strlen($string) >= 7) and preg_match("/^[\d\+\-]{7,20}$/", $string);
	}

	/* check mobile format */
	public static function is_mobile($string) {
		return is_string($string) and (strlen($string) >= 11) and preg_match("/^((\+86)|(86))?(1)\d{10}$/", $string);
	}

	/* is Identity card number */
	public static function is_IDCardNo($vStr) {
		$vCity = array(
			'11', '12', '13', '14', '15',
			'21', '22', '23',
			'31', '32', '33', '34', '35', '36', '37',
			'41', '42', '43', '44', '45', '46',
			'50', '51', '52', '53', '54',
			'61', '62', '63', '64', '65',
			'71',
			'81', '82',
			'91'
		);

		if(!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $vStr)) {
			return false;
		}
		if(!in_array(substr($vStr, 0, 2), $vCity)) {
			return false;
		}

		$vStr = preg_replace('/[xX]$/i', 'a', $vStr);
		$vLength = strlen($vStr);

		if($vLength == 18) {
			$vBirthday = substr($vStr, 6, 4).'-'.substr($vStr, 10, 2).'-'.substr($vStr, 12, 2);
		} 
		else{
			$vBirthday = '19'.substr($vStr, 6, 2).'-'.substr($vStr, 8, 2).'-'.substr($vStr, 10, 2);
		}
		if(date('Y-m-d', strtotime($vBirthday)) != $vBirthday) {
			return false;
		}

		if($vLength == 18) {
			$vSum = 0;
			for($i = 17; $i >= 0; $i--) {
				$vSubStr = substr($vStr, 17 - $i, 1);
				$vSum += (pow(2, $i) % 11) * (($vSubStr == 'a') ? 10 : intval($vSubStr , 11));
			}
			if($vSum % 11 != 1) {
				return false;
			}
		}
		return true;
	}

	/* alpha id */
	public static function alpha_id($id) {
		return preg_replace('/[^0-9a-zA-Z]+/', '', $id);
	}

	/* deal with search keyword */
	public static function keyword($keyword) {
		if(!is_scalar($keyword)) {
			return '';
		}

		if(MAGIC_QUOTES_GPC) {
			$keyword = stripslashes(trim($keyword));
		}
		$keyword = htmlspecialchars($keyword);
		$keyword = str_replace('\'', '', $keyword);
		$keyword = str_replace('"', '', $keyword);
		$keyword = preg_replace('/\s+/', ' ', $keyword);

		return $keyword;
	}

	/* text */
	public static function text($string, $strlen = false) {
		if(!is_scalar($string)) {
			return '';
		}

		$string = htmlspecialchars($string);
		if(0 < $strlen) {
			$string = AString::msubstr($string, $strlen);
		}
		return $string;
	}

	/* plain text without tags */
	public static function plain_text($string, $strlen = false) {
		if(!is_scalar($string)) {
			return '';
		}

		$string = preg_replace("/(\s|\&nbsp\;|　|\xc2\xa0)+/i", ' ', strip_tags($string));
		$string = htmlspecialchars($string);
		if(0 < $strlen) {
			$string = AString::msubstr($string, $strlen);
		}
		return $string;
	}

	/* url: such as img src */
	public static function url($string, $strlen = false) {
		if(!is_scalar($string)) {
			return '';
		}

		$string = strip_tags($string);
		$string = preg_replace('/([\x00-\x08\x0b-\x0c\x0e-\x19])/', '', $string);
		$string = preg_replace("/(\s|\&nbsp\;|　|\xc2\xa0|\"|\')+/i", '', $string);
		if(0 < $strlen) {
			$string = AString::msubstr($string, $strlen);
		}
		return $string;
	}

	/* trim script */
	public static function trim_script($string) {
		if(!is_scalar($string)) {
			return '';
		}

		$string = preg_replace('/\<([\/]?)script([^\>]*?)\>/si', '&lt;\\1script\\2&gt;', $string);
		$string = preg_replace('/\<([\/]?)iframe([^\>]*?)\>/si', '&lt;\\1iframe\\2&gt;', $string);
		$string = preg_replace('/\<([\/]?)frame([^\>]*?)\>/si', '&lt;\\1frame\\2&gt;', $string);
		$string = preg_replace('/]]\>/si', ']] >', $string);
		return $string;
	}

	/* remove browser XSS hack string */
	public static function remove_XSS($val, $ra= array(
			'javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base',
			'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')) {
		if(!is_scalar($val)) {
			return '';
		}

		$val = preg_replace('/([\x00-\x08\x0b-\x0c\x0e-\x19])/', '', $val);
		$search = 'abcdefghijklmnopqrstuvwxyz';
		$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
		$search .= '1234567890!@#$%^&*()';
		$search .= '~`";:?+/={}[]-_|\'\\';
		for($i = 0; $i < strlen($search); $i++) {
			$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
			$val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
		}

		$ra = array_filter($ra);
		if(empty($ra)) {
			return $val;
		}

		$found = true;
		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);
				$val = preg_replace($pattern, $replacement, $val);
				if($val_before == $val) {
					$found = false;
				}
			}
		}
		return $val;
	}

	public function __construct() {
	}
}

?>