<?php
/*
 * framework-spider
 * spider/BuildInformation.class.php
 * 
 * グローバル関数定義ファイル
 * spiderで利用するグローバル関数を定義するファイルです
 * 
 * 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(dirname(__FILE__)).DIRECTORY_SEPARATOR.'util'.DIRECTORY_SEPARATOR.'CharUtility.class.php');
/**
 * ビルドファイルを作成する情報を保持するデータオブジェクトクラス
 * 
 * @package spider spiderのコアパッケージ
 * @version 1.2.00
 * @copyright Copyright &copy; 2008, Framework-Spider Developer Team. <frameworkspider-dev@lists.sourceforge.jp> http://sourceforge.jp/projects/frameworkspider/
 * @author  Masanori Nakashima <m_nakashima@users.sourceforge.jp>
 * @since PHP 4.3
 */
class spider_BuildInformation {
	/** 実行ファイルパス	*/
	var $execute_file_path;
	/** リクエストページのURI	*/
	var $page_uri;
	/** ユーザーエージェント分類	*/
	var $agent_class				= null;
	/** 実行モジュール名配列		*/
	var $module_exec_info_hash		= array();
	/** ホットビルド機能：タイムスタンプ比較ファイル配列	*/
	var $compare_time_file_array	= array();
	/** ホットビルド機能：ファイル存在確認ファイル配列	*/
	var $confirm_exists_file_array	= array();
	/** 処理開始前実行コードハッシュ	*/
	var $processPreModuleHash		= array();
	/** 表示開始前実行コードハッシュ	*/
	var $processPreViewHash			= array();
	/** 表示後実行コードハッシュ	*/
	var $processPostViewHash		= array();
	/** 表示文字列に対する処理実行コードハッシュ	*/
	var $convert_view_process_hash	= array();
	/** 今後の拡張：出力ハンドラ	*/
	var $output_handler			= 'mb_output_handler';
	/** 今後の拡張：言語	*/
	var $output_language		= 'ja';
	/** 今後の拡張：出力文字セット	*/
	var $output_charset			= 'UTF-8';
	/** 今後の拡張：インターナル文字セット	*/
	var $internal_charset		= 'UTF-8';
	/** 今後の拡張：文字セット判断順序	*/
	var $detect_order			= 'UTF-8,EUC-JP,SJIS,SJIS-win,JIS,UTF-7';
	/**
	 * コンストラクタ
	 */
	function spider_BuildInformation() {
		$this->execute_file_path	= realpath($_SERVER['SCRIPT_FILENAME']);
		$this->getAgentClass();
		$this->_pickout_premodules();
	}
	/**
	 * ユーザーエージェント分類を取得します
	 */
	function getAgentClass() {
		if( !is_null($this->agent_class) ) {
			return $this->agent_class;
		}
		$this->agent_class	= 'default';
		foreach( $GLOBALS['SPIDER_USER_AGENT_CLASS_REGX_HASH'] as $regx_str => $agent_class ) {
			if( preg_match( $regx_str, $_SERVER['HTTP_USER_AGENT'] ) > 0 ) {
				$this->agent_class	= $agent_class;
				break;
			}
		}
		return $this->agent_class;
	}
	/**
	 * 対象ページのエージェント別URIを取得します
	 */
	function getAgentPageUri( $directory_separator='/' ) {
		return $this->agent_class.$this->getPageUri($directory_separator);
	}
	/**
	 * 実行ファイルのページURIを取得します
	 */
	function getPageUri( $directory_separator='/' ) {
		if( is_null($this->page_uri) ) {
			$this->page_uri	= SPIDER_URI_APP;
		}
		$page_uri	= $this->page_uri;
		$page_uri	= str_replace('/',$directory_separator,$page_uri);
		return $page_uri;
	}
	/**
	 * 実行ビルドファイルパスを取得します
	 */
	function getAgentPageBuildFilePath() {
		// 実行フォルダパスの変換を簡易にする
		$vartualRoot	= str_replace(DIRECTORY_SEPARATOR,'/',SPIDER_BASE_PATH);
		$appBaseUri		= str_replace(DIRECTORY_SEPARATOR,'/',SPIDER_URI_BASE);
		if( !defined('SPIDER_USE_ABSOLUTE_BIN_PATH') || SPIDER_USE_ABSOLUTE_BIN_PATH === false ) {
			// 実行ファイルパスをspiderの上層ディレクトリにする
			$cutPath		= str_replace(DIRECTORY_SEPARATOR,'/',dirname(DIR_PATH_SPIDER_DATA));
			$vartualRoot	= str_replace($cutPath,'',$vartualRoot);
		}
		if( strpos($vartualRoot,':') !== false ) {
			// windows対策に:を変換
			$vartualRoot	= str_replace(':','_CMA',dirname($vartualRoot));
		}
		if( strpos($vartualRoot,'/') === 0 ) {
			// /から始まるなら頭の/を除去
			$vartualRoot	= substr($vartualRoot,1);
		}
		$ps = strpos(SPIDER_URL_BASE,'https://');
		$isSSL = false;
		if( $ps !== false && $ps == 0 ) {
			$isSSL = true;
		}
		$nowHostName	= str_replace('-','__',str_replace(':','__',$_SERVER['HTTP_HOST']));
		if( $isSSL ) {
			$nowHostName	= 'ssl_P_'.$nowHostName;
		}
		$binFilePath	= DIR_PATH_BIN.'/'.$nowHostName.'/'.$vartualRoot
			.'/'.str_replace('-','_',str_replace('/','_',$appBaseUri))
			.'/'.$this->getAgentPageUri();
		if( strpos($binFilePath,DIRECTORY_SEPARATOR) !== false ){
			$binFilePath	= str_replace(DIRECTORY_SEPARATOR,'/',$binFilePath);
		}
		while( strpos($binFilePath,'//') !== false ){
			$binFilePath	= str_replace('//','/',$binFilePath);
		}
		if( !is_dir( dirname($binFilePath) ) ) {
			// 上位ディレクトリがないならディレクトリ階層を作成する
			$dirNameArray	= explode('/', dirname($binFilePath) );
			$dirPath		= array_shift($dirNameArray);
			foreach( $dirNameArray as $dirName ) {
				if( strlen($dirName) > 0 ) {
					$dirPath	.= '/'.$dirName;
					if( strlen($dirPath) > strlen(DIR_PATH_BIN) && !is_dir($dirPath) ) {
						if( @mkdir( $dirPath, SPIDER_PERMITTION_DATA_FOLDER ) ) {
							@chmod( $dirPath, SPIDER_PERMITTION_DATA_FOLDER );
						} else {
							header('Content-Type: text/plain;charset=UTF-8');
							die('Core Erorr! Can\'t create build file directoreis! '.$dirPath);
						}
					}
				}
			}
		}
		$binFilePath	= str_replace('/',DIRECTORY_SEPARATOR,$binFilePath);
		return $binFilePath;
	}
	/**
	 * プレモジュール取り出し
	 */
	function _pickout_premodules() {
		// 上位階層から確認してpre_module.inc.phpがあるか確認してモジュール追加
		$target_dir		= dirname( $this->execute_file_path );
		$target_dir		= str_replace("/",DIRECTORY_SEPARATOR,$target_dir);
		$target_dir		= str_replace("\\",DIRECTORY_SEPARATOR,$target_dir);
		$dir_name_array	= explode(DIRECTORY_SEPARATOR,$target_dir );
		$dir_path			= '';
		if( preg_match('/^[a-zA-Z]\\:/',$target_dir) ) {
			// Windowsなら頭にセパレータをつけないのでそのまま
		} else {
			// Unix系ならパスはディレクトリセパレータから開始
			$dir_path		= DIRECTORY_SEPARATOR;
		}
		// php.iniのbase_dirで読み込み階層が制限されていた場合の対策
		$spiderBaseDir	= dirname(DIR_PATH_SPIDER_DATA);
		foreach( $dir_name_array as $dirname ) {
			if( strlen($dirname) > 0 ) {
				$dir_path	.= $dirname.DIRECTORY_SEPARATOR;
				// php.iniのbase_dirで読み込み階層が制限されていた場合の対策
				if( strlen($dir_path) >= strlen($spiderBaseDir) ) {
					$pre_module_file	= $dir_path."pre_module.inc.php";
					if ( file_exists( $pre_module_file ) ) {
						$lines			= file( $pre_module_file );
						foreach ( $lines as $line ) {
							$line		= trim( $line );
							$this->addExecModuleByString( $line );
						}
						// ホットビルドタイムスタンプ比較ファイルに追加
						array_push( $this->compare_time_file_array, $pre_module_file );
					}
				}
			}
		}
	}
	/**
	 * 文字列を指定して実行モジュールハッシュに追加します
	 */
	function addExecModuleByString( $string ) {
		$string					= trim( $string );
		if( strlen($string) > 0 ) {
			$info_array					= explode(' ', $string);
			// ひとつめの要素は必ずモジュール名
			$module_name				= trim(array_shift($info_array));
			$info_hash					= array();
			// モジュール名と強制実行パラメータを情報ハッシュに設定
			$info_hash['module_name']	= $module_name;
			$info_hash['force']		= false;
			// 二つ目以降の要素を確認
			foreach( $info_array as $info ) {
				$info	= trim($info);
				if( preg_match('/^[pP][oO][sS][tT]\\(/',$info) > 0 ) {
					// 上書きPOSTパラメータ
					$val	= preg_replace('/^[pP][oO][sS][tT]\\(/','',$info);
					$val	= preg_replace('/\\)$/','',$val);
					$info_hash['post']	= $val;
				} else if( preg_match('/^[gG][eE][tT]\\(/',$info) > 0 ) {
					// 上書きGETパラメータ
					$val	= preg_replace('/^[gG][eE][tT]\\(/','',$info);
					$val	= preg_replace('/\\)$/','',$val);
					$info_hash['get']	= $val;
				} else if( preg_match('/^[aA][tT][tT][rR][iI][bB][uU][tT][eE]\\_[pP][rR][eE][fF][iI][xX]\\(/',$info) > 0 ) {
					// 上書きGETパラメータ
					$val	= preg_replace('/^[aA][tT][tT][rR][iI][bB][uU][tT][eE]\\_[pP][rR][eE][fF][iI][xX]\\(/','',$info);
					$val	= preg_replace('/\\)$/','',$val);
					$info_hash['attribute_prefix']	= $val;
				} else if( preg_match('/^[tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[fF][oO][rR][cC][eE]$/',$info) > 0 ) {
					// 強制実行かどうか
					if( preg_match('/^[tT][rR][uU][eE]|[fF][oO][rR][cC][eE]$/',$info) > 0 ) {
						$info_hash['force']	= true;
					} else {
						$info_hash['force']	= false;
					}
				}
			}
			// パラメータが異なる場合にキーを変更してハッシュに登録する。forceパラメータは参照しない
			if( isset($info_hash['post']) || isset($info_hash['get']) || isset($info_hash['attribute_prefix'])) {
				$keyname	= implode('',$info_hash);
				$this->module_exec_info_hash[$keyname]		= $info_hash;
			} else {
				$this->module_exec_info_hash[$module_name]	= $info_hash;
			}
		}
	}
	/**
	 * タイムスタンプ比較ファイルを追加します
	 */
	function addCompareFile( $file_path ) {
		if( strlen( $file_path ) > 0 && file_exists( $file_path ) ) {
			array_push( $this->compare_time_file_array, $file_path );
		}
		return true;
	}
	/**
	 * ビルド前ファイル存在確認ファイルを追加します
	 */
	function addConfirmFile( $file_path ) {
		if( strlen( $file_path ) > 0 && file_exists( $file_path ) ) {
			array_push( $this->confirm_exists_file_array, $file_path );
		}
		return true;
	}
}
?>