<?php
/**
 * 起動制御マネージャー
 *
 * コンテナ(フレームコンテナ、ウィジェットコンテナ、ウィジェット内サブコンテナ)の起動を行う。
 * このマネージャーでユーザのアクセス制御は行わない。
 *
 * PHP versions 5
 *
 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
 *
 * @package    Magic3 Framework
 * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
 * @copyright  Copyright 2006-2008 Magic3 Project.
 * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
 * @version    SVN: $Id: launchManager.php 425 2008-03-24 02:50:10Z fishbone $
 * @link       http://www.magic3.org
 */
class LaunchManager
{
	/**
	 * コンストラクタ
	 */
	function __construct()
	{
	}

	/**
	 * プログラムを実行
	 *
	 * @param string $filepath		呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
	 */
	function go($filepath = '')
	{
		global $gEnvManager;
		global $gRequestManager;

		// ルートから$filepathへの相対パスで「FrameContainer.php」の先頭につける
		// サフィックスを作成する
		// 例) 相対パスが「admin/index.php」のとき「admin_index」
		if ($filepath == ''){
			$basename = basename($_SERVER["PHP_SELF"], '.php');
		} else {
			// ルートまでのパスを削除
			$path = str_replace(M3_SYSTEM_ROOT_PATH, '', $filepath);
			$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
			$path = trim($path, '/');
			$pathArray = split('/', $path);
			$basename = '';
			for ($i = 0; $i < count($pathArray); $i++){
				if ($i == 0){
					$basename .= $pathArray[$i];
				} else {
					//$basename .= ucfirst($pathArray[$i]);
					$basename .= ('_' . $pathArray[$i]);
				}
			}
			$basename = basename($basename, '.php');
		}
		
		// ページIDを設定
		$gEnvManager->setCurrentPageId($basename);

		// ファイル名から、コンテナクラスファイル取り込み
		require_once($gEnvManager->getContainerPath() . '/' . $basename . 'FrameContainer.php');
		
		// コンテナクラスを起動
		$class = $basename . 'FrameContainer';
		$mainContainer = new $class();
		$mainContainer->process($gRequestManager);
	}
	/**
	 * ウィジェットプログラムを実行
	 *
	 * @param string $filepath		呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
	 */
	function goWidget($filepath)
	{
		global $gEnvManager;
		global $gRequestManager;
		static $pathArray = array();		// 呼び出し元を保存する

		$basename = basename($filepath, '.php');
		$widgetId = $gEnvManager->getCurrentWidgetId();// ウィジェットID
		
		// このメソッドにアクセスしたウィジェットのパスをみて、管理画面へのアクセスかどうかを判断
		$pathArray = explode(DIRECTORY_SEPARATOR, $filepath);
		$pathCount = count($pathArray);
		$accessAdmin = false;
		
		if ($gEnvManager->getIsMobile()){		// 携帯アクセスのとき
			// 管理画面へのアクセスかどうかチェック
			if ($pathArray[$pathCount -2] == 'admin' && $pathArray[$pathCount -3] == $widgetId){
				$accessAdmin = true;
			}
			// 携帯用ウィジェットのウィジェットIDは、「m/xxxxxx」の形式
			// ウィジェットIDを変換
			$widgetId = str_replace('/', '_', $widgetId);
			
			// コンテナクラス名作成
			if ($accessAdmin){
				$containerClass = 'admin_' . $widgetId . 'WidgetContainer';		// デフォルトで起動するコンテナクラス名「admin_ + ウィジェットID + WidgetContainer」
			} else {
				$containerClass = $widgetId . 'WidgetContainer';		// デフォルトで起動するコンテナクラス名「ウィジェットID + WidgetContainer」
				$containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
			}
			if (file_exists($containerPath)){
				require_once($containerPath);
			} else {
				echo 'file not found error: ' . $containerPath;
			}
			// コンテナクラスを起動
			$widgetContainer = new $containerClass();
			$widgetContainer->process($gRequestManager);
		} else {			// PC用の画面からのアクセスまたは管理画面へのアクセス
			// インナーウィジェットのチェック
			$isIWidget = false;
			if ($pathArray[$pathCount -4] == 'iwidgets' && $pathArray[$pathCount -2] == 'admin'){		// インナーウィジェット管理者画面
				$isIWidget = true;
				$widgetId = $pathArray[$pathCount -3];		// インナーウィジェットID
				$accessAdmin = true;
			} else if ($pathArray[$pathCount -3] == 'iwidgets'){	// インナーウィジェット通常画面
				$isIWidget = true;
				$widgetId = $pathArray[$pathCount -2];// インナーウィジェットID
			} else if ($pathArray[$pathCount -3] == $widgetId && $pathArray[$pathCount -2] == 'admin'){		// PC用ウィジェット管理画面
				$accessAdmin = true;
			} else if ($pathArray[$pathCount -4] . '/' . $pathArray[$pathCount -3] == $widgetId && $pathArray[$pathCount -2] == 'admin'){		// 携帯用ウィジェット管理画面
				$accessAdmin = true;
			}
			// コンテナクラス名作成
			if ($accessAdmin){
				$containerClass = 'admin_' . $widgetId . 'WidgetContainer';		// デフォルトで起動するコンテナクラス名「admin_ + ウィジェットID + WidgetContainer」
			} else {
				$containerClass = $widgetId . 'WidgetContainer';		// デフォルトで起動するコンテナクラス名「ウィジェットID + WidgetContainer」
			}
			// コンテナクラス名修正
			$containerClass = str_replace('/', '_', $containerClass);
					
			// コンテナクラスが既にロードされているときはエラー
			// 同じウィジェットが2回以上実行される可能性があるので、ウィジェットIDが同じであればエラーとしない
			if (class_exists($containerClass)){
				// 既に起動済みのウィジェットかどうかチェック
				//if (in_array($filepath, $pathArray)){
					// 同じウィジェットの場合は起動
					$widgetContainer = new $containerClass();
					$widgetContainer->process($gRequestManager);
	//			} else {
	//				// 同じウィジェットが起動されていないときは、クラス名のバッテイングでエラー
	//				echo 'class redefined error: ' . $containerClass;
	//			}
			} else {
				// ウィジェットのコンテナクラスファイルを読み込み
				//$containerPath = dirname($filepath) . '/include/container/' . $containerClass . '.php';
				if ($isIWidget){		// インナーウィジェットの場合
					if ($accessAdmin){
						$containerPath = dirname(dirname($filepath)) . '/include/container/' . $containerClass . '.php';
					} else {
						$containerPath = dirname($filepath) . '/include/container/' . $containerClass . '.php';
					}
				} else {
					$containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
				}
				if (file_exists($containerPath)){
					require_once($containerPath);
				} else {
					echo 'file not found error: ' . $containerPath;
				}
				// コンテナクラスを起動
				$widgetContainer = new $containerClass();
				$widgetContainer->process($gRequestManager);
			}
			// 呼び出し元ファイルパスの保存
			$pathArray[] = $filepath;
		}
	}
	/**
	 * ウィジェットプログラム(サブ)を実行
	 *
	 * @param string $task		タスク名
	 * @param bool $isAdmin		管理者機能(adminディレクトリ以下)かどうか
	 */
	function goSubWidget($task, $isAdmin = false)
	{
		global $gEnvManager;
		global $gRequestManager;
		
		// コンテナクラス名作成
		// フォーマット: [ウィジェットID][タスク名]WidgetContainer
		$widgetId = $gEnvManager->getCurrentWidgetId();// ウィジェットID
		$containerClass = '';
		if ($isAdmin) $containerClass .= 'admin_';
		$containerClass .= $widgetId . ucfirst($task) . 'WidgetContainer';

		// コンテナクラスが既にロードされているときはエラー
		if (class_exists($containerClass)){
			echo 'class redefined error2: ' . $containerClass;
		} else {
			// コンテナクラスファイル取り込み
			$containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
			if (file_exists($containerPath)){
				require_once($containerPath);
			} else {
				echo 'file not found error: ' . $containerPath;
			}
			// コンテナクラスを起動
			$widgetContainer = new $containerClass();
			$widgetContainer->process($gRequestManager);
		}
	}
	/**
	 * ウィジェットインストーラ、アンインストーラを実行
	 *
	 * @param int $install					インストール種別(0=インストール、1=アンインストール、2=アップグレード)
	 */
	function goInstallWidget($install)
	{
		global $gEnvManager;
		global $gRequestManager;
		
		// コンテナクラス名作成
		$widgetId = $gEnvManager->getCurrentWidgetId();// ウィジェットID
		$containerClass = 'admin_';
		$containerClass .= $widgetId . 'InstallWidgetContainer';

		// コンテナクラスが既にロードされているときはエラー
		if (class_exists($containerClass)){
			echo 'class redefined error3: ' . $containerClass;
		} else {
			// コンテナクラスファイル取り込み
			$containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
			if (file_exists($containerPath)){
				require_once($containerPath);
			} else {		// インストーラが存在しないときは終了
				return;
			}
			// コンテナクラスを起動
			$widgetContainer = new $containerClass();
			$widgetContainer->process($gRequestManager, $install);
		}
	}
	/**
	 * 携帯用プログラムを実行
	 *
	 * @param string $filepath		呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
	 */
	function goMobile($filepath = '')
	{
		global $gEnvManager;
		global $gRequestManager;

		// 携帯からのアクセスを設定
		$gEnvManager->setIsMobile(true);
		
		// ルートから$filepathへの相対パスで「FrameContainer.php」の先頭につける
		// サフィックスを作成する
		// 例) 相対パスが「admin/index.php」のとき「admin_index」
		if ($filepath == ''){
			$basename = basename($_SERVER["PHP_SELF"], '.php');
		} else {
			// ルートまでのパスを削除
			$path = str_replace(M3_SYSTEM_ROOT_PATH, '', $filepath);
			$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
			$path = trim($path, '/');
			$pathArray = split('/', $path);
			$basename = '';
			for ($i = 0; $i < count($pathArray); $i++){
				if ($i == 0){
					$basename .= $pathArray[$i];
				} else {
					//$basename .= ucfirst($pathArray[$i]);
					$basename .= ('_' . $pathArray[$i]);
				}
			}
			$basename = basename($basename, '.php');
		}
		
		// ページIDを設定
		$gEnvManager->setCurrentPageId($basename);

		// ファイル名から、コンテナクラスファイル取り込み
		require_once($gEnvManager->getContainerPath() . '/' . $basename . 'FrameContainer.php');
		
		// コンテナクラスを起動
		$class = $basename . 'FrameContainer';
		$mainContainer = new $class();
		$mainContainer->process($gRequestManager);
	}
}
?>
