<?php
/*
 * PHP version 5
 *
 * @copyright Copyright 2010, Cake. (http://trpgtools-onweb.sourceforge.jp/)
 * @category CSS
 * @package  TRPG Data Bank
 * @version  beta
 * @author   Cake <cake_67@users.sourceforge.jp>
 * @license  http://www.opensource.org/licenses/mit-license.php The MIT License
 * @link     http://trpgtools-onweb.sourceforge.jp/
 *
 * 独自のSanitize、逆Sanitizeの追加Behavoir
 * The behavoir of the additional Sanitize rules, reverse-Sanitize rules.
 */

app::import('Sanitize');

class SanitizePlusBehavior extends ModelBehavior {

	var $settings = array();

	// ユーザに使用を許可するタグ
	var $usertag_whitelist = array(
		'a',
		'b', 'i', 's', 'u','tt', 
		'font', 'big', 'small',
		'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 
		'div', 'p', 'span', 'center', 'pre', 'blockquote', 
		'hr', 
		'br', 'nobr', 'wbr',
		'ul', 'ol', 'li', 'dl', 'dd', 'dt', 
		'table', 'tr', 'th', 'td', 'thead', 'tbody', 'tfoot',
	);

	function setup(&$model, $config = array()) {
		$this->settings = $config;
	}

	/* 各modelに設定した$fieldsの設定でSanitize */
	// Sanitize::clean(),Sanitize::escape()以外
	function escapeByFields(&$model, $field, $string)
	{
		if (isset($model->fields['escape'][$field]['all']) && $model->fields['escape'][$field]['all']) {
			$string = self::stripWhitespace($string);
		} else {
			if (isset($model->fields['escape'][$field]['whitespace']) && $model->fields['escape'][$field]['whitespace']) {
				$string = self::stripWhitespace($string);
			}
			if (isset($model->fields['escape'][$field]['images']) && $model->fields['escape'][$field]['images']) {
				$string = Sanitize::stripImages($string);
			}
			if (isset($model->fields['escape'][$field]['sctipts']) && $model->fields['escape'][$field]['sctipts']) {
				$string = Sanitize::stripScripts($string);
			}
//			$characters_has_profiles[$k]['value'] = str_replace(array("\n\r", '\n', "\r"), '<br />', $characters_has_profiles[$k]['value']);
			$string = str_replace("\\", '', $string);
		}
		if (isset($model->fields['escape'][$field]['tags']) && $model->fields['escape'][$field]['tags']) {
			$string = self::stripTags($string);
		}
		if (isset($model->fields['escape'][$field]['html']) && $model->fields['escape'][$field]['html']) {
			$string = Sanitize::html($string);
		}
		return $string;
	}

	// Sanitize::stripWhitespace($str) バックスラッシュ手入力対応用
	function stripWhitespace($str) 
	{
		$str = preg_replace('/\\\n/', '', $str);
		$str = preg_replace('/\\\r/', '', $str);
		return Sanitize::stripWhitespace($str);
	}
	function stripAll($str) 
	{
		$str = self::stripWhitespace($string);
		return Sanitize::stripAll($str);
	}


	/* reverse-Sanitize */
	/* return HTML tags from HTML entities.
	 * base on ver1.2.5
	 * @param string $string Sanitized Data
	 * @param boolean $strip_all If true, Sanitized by Sanitize::stripAll(), and NO NEEW to set below 3 $args.
	 * @param boolean $strip_scripts If true, Sanitized by Sanitize::stripScripts()
	 * @param boolean $strip_images If true, Sanitized by Sanitize::stripImages()
	 * @param boolean $strip_whitespace If true, Sanitized by Sanitize::stripWhitespace()
	 * return Data reverted HTML tags
	 */
	function restore_html(&$model, $string, $strip_all = false, $strip_scripts = true, $strip_images = true, $strip_whitespace = false, $strip_tag = false) {
		if (empty($string)) {
			return $string;
		}

		$patterns = array("/\&amp;/", "/\&#37;/", "/\&lt;/", "/\&gt;/", "/\&quot;/", "/\&#39;/", "/\&#40;/", "/\&#41;/", "/\&#43;/", "/\&#45;/", '/\\\"/', "/\\\'/");
		$replacements = array("&", "%", "<", ">", '"', "'", "(", ")", "+", "-", '"', "'");

		$string = preg_replace($patterns, $replacements, $string);
		$string = preg_replace('/\\\n/', "\n", $string);

		if ($strip_all) {
			$string = Sanitize::stripAll($string);
		} else {
			if ($strip_scripts) {
				$string = Sanitize::stripScripts($string);
			}
			if ($strip_images) {
				$string = Sanitize::stripImages($string);
			}
			if ($strip_whitespace) {
				$string = Sanitize::stripImages($string);
			}
			if ($strip_tag) {
				$string = Sanitize::stripTags($string);
			}
		}

		return $string;
	}

/**
 * Strips the all tags .
 *
 * @param string $str String to sanitize
 * @return string sanitized String
 * @access public
 * @static
 */
	function stripTags($str)
	{
		$str = preg_replace('/<[\/\!]*?[^<>]*?>/si', '', $str);

		return $str;
	}

	function deleteDangerOptions($str)
	{
		if (empty($str)) {
			return $str;
		}

		$pattern = array(
			'/style=[\"\']?[^>]*[\"\']?>/si',
			'/on[\w]+=[\"\']?[^>]*[\"\']?>/si',
			'/url\(.*\)/',
		);
		$replacement = array(
			'>',
			'>',
			'',
		);

		return preg_replace($pattern, $replacement, $str);
	}

	function convertTag($str, $tag)
	{
		if (empty($str) || empty($tag)) {
			return $str;
		}

		$pattern = '/<(\/)?'. $tag. '(\s[^>]*)?>/si';
		$replacement = '[$1'. $tag. '$2]';

		$str = preg_replace($pattern, $replacement, $str);

		return $str;
	}
	function restoreTag($str, $tag)
	{
		if (empty($str) || empty($tag)) {
			return $str;
		}

		$pattern = '/\[(\/)?'. $tag. '(\s[^\]]*)?\]/si';
		$replacement = '<$1'. $tag. '$2>';

		$str = preg_replace($pattern, $replacement, $str);

		return $str;
	}

	function convertCss($str)
	{
		$pattern = '/<style type=\"text\/css\">[\n\r]?<!--([^<|^>]+)-->[\n\r]?<\/style>/';
		$replacement = '[css]$1[/css]';

		return preg_replace($pattern, $replacement, $str);
	}
	function restoreCss($str)
	{
		$pattern = array(
			'/\[css\]/',
			'/\[\/css\]/',
		);
		$replacement = array(
			"<style type=\"text/css\"><!--\n",
			"\n--></style>",
		);

		return preg_replace($pattern, $replacement, $str);
	}

	/* タグ文字(<>)をエスケープ 
	*/
	function escapeTags(&$model, $string, $options = array())
	{
		if (empty($string)) {
			return $string;
		}

		$patterns= array("<", ">");
		$replacements = array('&lt;', '&gt;');

		$string = str_replace($patterns, $replacements, $string);

		return $string;
	}

	/* return SQL descaped strings.
	 */
	function restore_escape(&$model, $string) {

		return stripslashes($string);
	}

	/* Tags */
	// 指定のタグを[font size=XXX]などの形にstripしてからSanitize
	// styleは<style type="text/css">～</style>のみ許可
	// on***や styleは削除
	function stripWhiteTags($data)
	{
		if (empty($data)) {
			return $data;
		}
		if (is_array($data)) {
			foreach($data as $k => $v) {
				$data[$k] = $this->stripWhiteTags($v);
			}
		}

		// <style type="text/css">～</style>のエスケープ
		$data = self::convertCss($data);

		$data = Sanitize::stripImages($data);
		$data = Sanitize::stripScripts($data);

		// style=, on***=, url(***)を削除
		$data = self::deleteDangerOptions($data);

		foreach($this->usertag_whitelist as $tag) {
			$data = self::convertTag($data, $tag);
		}

		$data = str_replace("\\", '', $data);
		$data = self::stripTags($data);

		return $data;
	}
	function restoreWhiteTags($data, $restoreCSS = true, $white_list = array())
	{
		if (empty($data)) {
			return $data;
		}
		if (is_array($data)) {
			foreach($data as $k => $v) {
				$data[$k] = $this->restoreWhiteTags($v, $white_list);
			}
		}

		if ($restoreCSS) {
			$data = self::restoreCss($data);
		}

		if (empty($white_list)) {
			$white_list = $this->usertag_whitelist;
		}

		foreach($white_list as $tag) {
			$data = self::restoreTag($data, $tag);
		}

		return $data;

	}
}
