<?php
/*
 * framework-spider
 * spider/tags/Widget.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用変換タグ:ウィジェットタグ変換クラス
 * 
 * {widget:[ウィジェットファイル名] [オプション文字列]}
 * ブラウザに応じて準備されたDATA/widgetフォルダ内のファイルに記述された文字列を適用します。
 * 
 * ブラウザごとの振り分けフォルダの定義はDATA/define.inc.phpの記述に準じます。
 * ターゲットブラウザのフォルダが見つからない場合は、defaultフォルダ内を検索します。
 * 
 * 指定できるオプション）
 * dynamic
 *    dynamicをオプション文字列内に記述することで動的ウィジェットとして動作します。
 * 
 * 動的ウィジェットタグは、呼び出すウィジェットの内容を以下の順序で動的に制御します。
 * この機能の追加により、ページレイアウトの一部分だけ変更したい時にテンプレートを増やす必要がなくなります。
 * 
 * 【動的ウィジェット取り込み優先順位】
 * １） 表示しようとしているページのURIと同じ階層で同じファイル名のファイルがwidgetsフォルダ内にあれば
 *       そのファイルをページ特有のウィジェットとして取り込む
 * ２） 上記が存在しなかった場合、widgetsフォルダ内の同一階層フォルダにある、[ウィジェットファイル名]を
 *       探し、あればそのファイルをウィジェットとして取り込む。
 * ３） 同一フォルダ内になければ、widgetsフォルダ内をさかのぼり、[ウィジェットファイル名]のファイルを見つけた
 *       たらそのファイルをウィジェットとして取り込む。
 * 
 * @package spider spiderのコアパッケージ
 * @version 1.2.00
 * @copyright Copyright &copy; 2009, <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_Widget extends spider_tags_TagBase {
	/**
	 * コンストラクタ
	 */
	function spider_tags_Widget() {
		$this->priority		= 3;
		$this->tag_name		= 'widget';
	}
	/**
	 * 個々のタグ文字列の変換後文字列を取得します
	 */
	function getConvertedStrings( &$result_strings, &$buildInformation, $option_array=array(), $valiable_counter=0 ) {
		$widget_file		= $option_array[0];
		$widgetFilePath	= false;
		if( in_array('dynamic',$option_array) ) {
			$widgetFilePath	= $this->getDynamicWidgetFilePath( $widget_file, $buildInformation );
		} else {
			$widgetFilePath	= $this->getAvailableWidgetFilePath( $widget_file, $buildInformation );
		}
		if ( false !== $widgetFilePath && file_exists( $widgetFilePath ) ) {
			// ウィジェット出力文字列取得
			$widget_strings		= trim(file_get_contents( $widgetFilePath ));
			if( preg_match('/^\\{widget\\-link\\:[^\\}]*?\\}$/',$widget_strings) > 0 ) {
				// ウィジェットファイルの中身がウィジェットリンクを指定しているならウィジェットファイルを再取得する
				$widget_file	= preg_replace('/^\\{widget\\-link\\:/','',$widget_strings);
				$widget_file	= trim(preg_replace('/\\}$/','',$widget_file));
				// リンクは必ず静的呼び出し
				$widgetFilePath	= $this->getAvailableWidgetFilePath( $widget_file, $buildInformation );
				if ( false !== $widgetFilePath && file_exists( $widgetFilePath ) ) {
					$widget_strings		= trim(file_get_contents( $widgetFilePath ));
				} else {
					return '[widget file for '.$buildInformation->agent_class.' is not found!]';
				}
			}
			// ウィジェットの改行コードを統一
			$widget_strings = str_replace( "\r\n", "\n" , $widget_strings );
			$widget_strings = str_replace( "\r", "\n" , $widget_strings );
			return $widget_strings;
		} else {
			// ウィジェットファイルが見つからない場合に無限ループにならないよう文字列を出力
			return '[widget file for '.$buildInformation->agent_class.' is not found!]';
		}
	}
	/**
	 * ユーザーエージェント分類にあったウィジェットファイルのパスを取得する
	 * @param $fileName 使用するウィジェットファイル名
	 */
	function getAvailableWidgetFilePath( $fileName, & $buildInformation ) {
		$agentClass		= trim($buildInformation->agent_class);
		// 指定エージェントのファイル
		$widgetFilePath	= $this->getAgentWidgetFilePath( $fileName, $agentClass );
		if( false === $widgetFilePath ) {
			return false;
		} else if( file_exists($widgetFilePath) ) {
			$buildInformation->addCompareFile( $widgetFilePath );
			return $widgetFilePath;
		} else {
			$buildInformation->addConfirmFile( $widgetFilePath );
		}
		// 代替エージェントのファイル
		$altAgent	= null;
		if( is_array($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'])
			&& count($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH']) > 0 ) {
			$altAgent	= $buildInformation->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];
				$widgetFilePath		= $this->getAgentWidgetFilePath( $fileName, $altAgent );
				if( false === $widgetFilePath ) {
					return false;
				} else if( file_exists($widgetFilePath) ) {
					$buildInformation->addCompareFile( $widgetFilePath );
					return $widgetFilePath;
				} else {
					$buildInformation->addConfirmFile( $widgetFilePath );
				}
			}
		}
		// デフォルトのファイル
		$widgetFilePath	= $this->getAgentWidgetFilePath( $fileName, 'default' );
		if( false === $widgetFilePath ) {
			return false;
		} else if( file_exists($widgetFilePath) ) {
			$buildInformation->addCompareFile( $widgetFilePath );
			return $widgetFilePath;
		} else {
			$buildInformation->addConfirmFile( $widgetFilePath );
		}
		return false;
	}
	/**
	 * ユーザーエージェント分類にあったウィジェットファイルのパスを取得する
	 * @param $fileName 使用するウィジェットファイル名
	 */
	function getDynamicWidgetFilePath( $fileName, & $buildInformation ) {
		if( !defined('DIR_PATH_WIDGETS')
			|| strlen(DIR_PATH_WIDGETS) == 0
			|| !is_dir( DIR_PATH_WIDGETS ) ) {
			return false;
		}
		$agentClass		= trim($buildInformation->agent_class);
		// ダイレクトページウィジェット名を作成
		$pageUri				= $buildInformation->getPageUri();
		$selfName				= basename($pageUri);
		$directPageWidgetUri	= preg_replace('/'.util_CharUtility::escapeRegxStr($selfName).'$/',$fileName.'.'.$selfName,$pageUri);
		// 最初にウィジェットフォルダの同じURIにファイルがあるか確認しあれば返す
		$widgetFilePath = DIR_PATH_WIDGETS
			.'/'.$agentClass
			.$directPageWidgetUri;
		if( file_exists($widgetFilePath) ) {
			$buildInformation->addCompareFile( $widgetFilePath );
			return $widgetFilePath;
		} else {
			$buildInformation->addConfirmFile( $widgetFilePath );
		}
		// 代替エージェントのURIファイルを探す
		$altAgentClass	= $agentClass;
		if( is_array($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'])
		&& count($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH']) > 0 ) {
			while( isset($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgentClass])
			&& strlen($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgentClass]) > 0 ) {
				$altAgentClass	= $GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgentClass];
				$widgetFilePath = DIR_PATH_WIDGETS
					.'/'.$altAgentClass
					.$directPageWidgetUri;
				if( file_exists($widgetFilePath) ) {
					$buildInformation->addCompareFile( $widgetFilePath );
					return $widgetFilePath;
				} else {
					$buildInformation->addConfirmFile( $widgetFilePath );
				}
			}
		}
		// デフォルトのユーザーエージェントURLファイルを探す
		$widgetFilePath = DIR_PATH_WIDGETS
			.'/default'
			.$directPageWidgetUri;
		if( file_exists($widgetFilePath) ) {
			$buildInformation->addCompareFile( $widgetFilePath );
			return $widgetFilePath;
		} else {
			$buildInformation->addConfirmFile( $widgetFilePath );
		}
		
		// URIファイルが存在しない場合、ディレクトリをさかのぼりながら指定名のウィジェットファイルを探す
		$targetDirUri	= str_replace(DIRECTORY_SEPARATOR,'/',dirname($directPageWidgetUri));
		$targetDirUri	= preg_replace('/^\\//','',$targetDirUri);
		do {
			$target_file_name	= $targetDirUri.'/'.$fileName;
			// 指定ユーザエージェントのウィジェット
			$widgetFilePath	= $this->getAgentWidgetFilePath( $target_file_name, $agentClass );
			if( false === $widgetFilePath ) {
				return false;
			} else if( file_exists($widgetFilePath) ) {
				$buildInformation->addCompareFile( $widgetFilePath );
				return $widgetFilePath;
			} else {
				$buildInformation->addConfirmFile( $widgetFilePath );
			}
			// 代替エージェントのファイル
			$altAgentClass	= $agentClass;
			if( is_array($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'])
			&& count($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH']) > 0 ) {
				while( isset($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgentClass])
				&& strlen($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgentClass]) > 0 ) {
					$altAgentClass	= $GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$altAgentClass];
					$widgetFilePath	= $this->getAgentWidgetFilePath( $target_file_name, $altAgentClass );
					if( false === $widgetFilePath ) {
						return false;
					} else if( file_exists($widgetFilePath) ) {
						$buildInformation->addCompareFile( $widgetFilePath );
						return $widgetFilePath;
					} else {
						$buildInformation->addConfirmFile( $widgetFilePath );
					}
				}
			}
			// デフォルトのファイル
			$widgetFilePath	= $this->getAgentWidgetFilePath( $target_file_name, 'default' );
			if( false === $widgetFilePath ) {
				return false;
			} else if( file_exists($widgetFilePath) ) {
				$buildInformation->addCompareFile( $widgetFilePath );
				return $widgetFilePath;
			} else {
				$buildInformation->addConfirmFile( $widgetFilePath );
			}
			// 一つ上のフォルダに移動
			$targetDirUri	= dirname( $targetDirUri );
		} while  ( strlen($targetDirUri) > 0 );
		return false;
	}
	/**
	 * ユーザーエージェント分類に応じたウィジェットファイルパスを取得します
	 * （ファイル存在確認なし）
	 */
	function getAgentWidgetFilePath( $fileName, $agentClass ) {
		$agentClass	= trim($agentClass);
		$fileName	= trim($fileName);
		if( strlen( $agentClass ) == 0 ) {
			return false;
		}
		if( strlen( $fileName ) == 0 ) {
			return false;
		}
		if( !defined('DIR_PATH_WIDGETS')
			|| strlen(DIR_PATH_WIDGETS) == 0
			|| !is_dir( DIR_PATH_WIDGETS ) ) {
			return false;
		}
		$widgetFilePath = DIR_PATH_WIDGETS
			.'/'.$agentClass
			.'/'.$fileName;
		return $widgetFilePath;
	}
}
?>