<?php
/*
 * framework-spider
 * spider/tags/Template.class.php
 * 
 * CopyRight(C)Framework-Spider Developer Team. 2010. All Right Reserved. 
 * URL         : http://sourceforge.jp/projects/frameworkspider/
 * Mail        : frameworkspider-dev@lists.sourceforge.jp
 * Auther      : Masanori Nakashima
 * Modifier    : Masanori Nakashima
 * Last Updated: 2010.06.23
 * 
 */
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'TagBase.class.php');
/**
 * HTML用変換タグ：テンプレートタグクラス
 * 
 * {template:[テンプレートファイル名]}
 * で指定することでページを表示する際の外側テンプレートを適用します。
 * テンプレートファイルはDATA/templatesフォルダ内の対象ブラウザフォルダ内を検索し、
 * 対象ブラウザが存在しなければDATA/templates/defaultフォルダ内のテンプレートを適用します。
 * defaultにもターゲットテンプレートが存在しない場合、テンプレート自体を利用しません。
 * 
 * ブラウザごとの振り分けフォルダの定義はDATA/define.inc.phpの記述に準じます。
 * ターゲットブラウザのフォルダが見つからない場合は、defaultフォルダ内を検索します。
 * 
 * ※このタグは一つのページ内に1つしか記述することができません。
 * 複数指定された場合、ページ内の一番最後に記述されたテンプレートファイル名が有効になります。
 * 
 * @package spider spiderのコアパッケージ
 * @version 1.2.00
 * @copyright Copyright &copy; 2008, <m_nakashima@users.sourceforge.jp> http://sourceforge.jp/projects/shopformer/
 * @author  m.nakashima <m_nakashima@users.sourceforge.jp>
 * @since PHP 4.3
 */
class spider_tags_Template extends spider_tags_TagBase {

	/**
	 * コンストラクタ
	 */
	function spider_tags_Template() {
		$this->priority	= 0;
	}
	/**
	 * コンバートメソッド
	 */
	function convert( &$result_strings, &$buildInformationObject ){
		// テンプレートファイル名
		$template_name	= null;
		// 外側テンプレートを確認し、一番末尾にでるテンプレートを適用
		preg_match_all( '/\\{tpl\\-outer\\:[^\\}]*?\\}/'
			, $result_strings
			, $output_array
			, PREG_PATTERN_ORDER );
		foreach ( $output_array as $output ) {
			foreach ( $output as $target ) {
				$template_name	= preg_replace( '/\\{tpl\\-outer\\:/','', $target );
				$template_name	= preg_replace( '/\\}/','', $template_name );
				$result_strings = str_replace( "\n".$target."\n", "", $result_strings );
				$result_strings = str_replace( $target, "", $result_strings );
				$template_name	= trim($template_name);
			}
		}
		preg_match_all( '/\\{template\\:[^\\}]*?\\}/'
			, $result_strings
			, $output_array
			, PREG_PATTERN_ORDER );
		foreach ( $output_array as $output ) {
			foreach ( $output as $target ) {
				$template_name	= preg_replace( '/\\{template\\:/','', $target );
				$template_name	= preg_replace( '/\\}/','', $template_name );
				$result_strings = str_replace( "\n".$target."\n", "", $result_strings );
				$result_strings = str_replace( $target, "", $result_strings );
				$template_name	= trim($template_name);
			}
		}
		// tpl-typeがあるならユーザーエージェント分類を強制上書き
		preg_match_all( '/\\{tpl\\-type\\:[^\\}]*?\\}/'
			, $result_strings
			, $output_array
			, PREG_PATTERN_ORDER );
		foreach ( $output_array as $output ) {
			foreach ( $output as $target ) {
				$template_type	= preg_replace( '/\\{tpl\\-type\\:/','', $target );
				$template_type	= preg_replace( '/\\}/','', $template_type );
				$result_strings = str_replace( "\n".$target."\n", "", $result_strings );
				$result_strings = str_replace( $target, "", $result_strings );
				$template_type	= trim($template_type);
				$buildInformationObject->agent_class	= $template_type;
			}
		}
		
		// 外側テンプレート適用
		$templateOuterString	= $result_strings;
		if ( !is_null( $template_name ) ) {
			$template_file_path	= $this->getRealTemplateFilePath( $template_name, $buildInformationObject );
			if( $template_file_path !== false ) {
				// テンプレートファイルの内容を取得
				$templateOuterString	= file_get_contents( $template_file_path );
				// xml宣言はphpと相性が悪い為置換
				if( preg_match('/<\\?xml([^\\>]+)\\?>/', $templateOuterString ) > 0
					&& preg_match('/<\\?php\\secho([^<]+)<\\?xml([^\\>]+)\\?>/', $templateOuterString ) == 0 ) {
					$templateOuterString	= preg_replace('/<\\?xml([^\\>]+)\\?>/','<?php echo \'<?xml${1}?>\'."\n"; ?>',$templateOuterString);
				}
				// テンプレートの改行コードを統一
				$templateOuterString = str_replace( "\r\n", "\n" , $templateOuterString );
				$templateOuterString = str_replace( "\r", "\n" , $templateOuterString );
				// 記述式を変更
				$templateOuterString	= str_replace( '{page-contents}'
					, $result_strings
					, $templateOuterString );
			}
		}
		// 子テンプレート呼び出し箇所の確認
		$child_template_tag_aray		= array();
		while( preg_match_all( '/\\{tpl\\:[^\\}]*?}/'
			, $templateOuterString
			, $child_template_tag_aray
			, PREG_PATTERN_ORDER ) > 0 ) {
			foreach ( $child_template_tag_aray as $child_template_tags ) {
				foreach ( $child_template_tags as $child_template_tag ) {
					$child_template_file	= preg_replace( '/\\{tpl\\:/','', $child_template_tag );
					$child_template_file	= preg_replace( '/\\}$/','', $child_template_file );
					$child_template_file_path = $this->getRealTemplateFilePath( $child_template_file, $buildInformationObject );
					if ( false !== $child_template_file_path && file_exists( $child_template_file_path ) ) {
						// 子テンプレート出力文字列取得
						$child_template_lines		= file( $child_template_file_path );
						$child_template_strings		= implode( "", $child_template_lines );
						// 子テンプレートの改行コードを統一
						$child_template_strings = str_replace( "\r\n", "\n" , $child_template_strings );
						$child_template_strings = str_replace( "\r", "\n" , $child_template_strings );
						// テンプレート文字列に子テンプレートの出力
						$templateOuterString = str_replace( $child_template_tag, $child_template_strings, $templateOuterString );
					} else {
						// テンプレートファイルが見つからない場合に無限ループにならないよう警告文に置換
						$templateOuterString = str_replace( $child_template_tag, '['.$child_template_file_path.'template file is not found!]', $templateOuterString );
					}
				}
			}
		}
		// フォルダデフォルトファイルの適用
		$folderDefaultPath		= null;
		$folder_path				= dirname($buildInformationObject->execute_file_path);
		// 存在しなかった場合の存在確認比較ファイルパス
		$confirm_default_path_array	= array();
		while( strlen($folder_path) >= strlen(SPIDER_BASE_PATH) ) {
			$folderDefaultPath	= $folder_path.'/.default';
			if( file_exists( $folderDefaultPath ) ) {
				break;
			} else {
				array_push( $confirm_default_path_array, $folderDefaultPath );
				$folderDefaultPath	= null;
			}
			$folder_path			= dirname($folder_path);
		}
		if( !is_null( $folderDefaultPath ) && file_exists($folderDefaultPath) ) {
			$str	= trim(file_get_contents($folderDefaultPath));
			$templateOuterString	= $str.$templateOuterString;
			// フォルダデフォルトファイルをタイムスタンプ比較ファイルに追加
			$buildInformationObject->addCompareFile( $folderDefaultPath );
		} else if( count( $confirm_default_path_array ) > 0 ) {
			foreach( $confirm_default_path_array as $path ) {
				$buildInformationObject->addConfirmFile( $path );
			}
		}
		$result_strings		= $templateOuterString;
	}
	/**
	 * ユーザーエージェント分類にあったテンプレートファイルのパスを取得する
	 * @param $file_name 使用するテンプレートファイル名
	 */
	function getRealTemplateFilePath( $file_name, &$buildInformationObject ) {
		$agent_class	= trim($buildInformationObject->agent_class);
		if( strlen(trim($agent_class)) == 0 ) {
			$agent_class	= 'default';
		}
		$template_file_path = DIR_PATH_TEMPLATES
			.'/'.$agent_class
			.'/'.$file_name;
		if( file_exists($template_file_path) ) {
			// 存在するならタイムスタンプ比較に追加してリターン
			$buildInformationObject->addCompareFile( $template_file_path );
			return $template_file_path;
		} else {
			// 存在しないなら存在確認に追加
			$buildInformationObject->addConfirmFile( $template_file_path );
		}

		$altAgent	= null;
		if( is_array($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'])
			&& count($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH']) > 0 ) {
			$altAgent	= $buildInformationObject->agent_class;
			while( isset($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgent])
				&& strlen($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgent]) > 0 ) {
				$altAgent			= $GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgent];
				$templateFilePath	= DIR_PATH_TEMPLATES
					.'/'.$altAgent.'/'.$file_name;
				if( file_exists($templateFilePath) ) {
					// 存在するならタイムスタンプ比較に追加してリターン
					$buildInformationObject->addCompareFile( $templateFilePath );
					return $templateFilePath;
				} else {
					// 存在しないなら存在確認に追加
					$buildInformationObject->addConfirmFile( $templateFilePath );
				}
			}
		}
		// 代替ユーザーエージェント分類が指定されていないならdefault
		$template_file_path = DIR_PATH_TEMPLATES
			.'/'.'default'
			.'/'.$file_name;
		if( file_exists( $template_file_path ) ) {
			// 存在するならタイムスタンプ比較に追加してリターン
			$buildInformationObject->addCompareFile( $template_file_path );
			return $template_file_path;
		} else {
			// 存在しないなら存在確認に追加
			$buildInformationObject->addConfirmFile( $template_file_path );
		}
		return false;
	}
}
?>