<?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: pageManager.php 725 2008-06-10 07:09:30Z fishbone $
 * @link       http://www.magic3.org
 */
class PageManager
{
	private $popupMsg;				// ポップアップダイアログメッセージ
	private $showPositionMode;			// ポジション表示モード
	private $showWidget;			// ウィジェットの単体表示
	private $systemHandleMode;			// システム制御遷移モード(1=サイト非公開時)
	private $tmpData;				// データ作成用
	private $db;					// DBオブジェクト
	private $defaultScriptFiles;	// デフォルトで読み込むスクリプトファイル
	private $defaultCssFiles;		// デフォルトで読み込むCSSファイル
	private $defaultAdminScriptFiles;	// デフォルトで読み込むスクリプトファイル(管理用)
	private $defaultAjaxLibFile;	// デフォルトのAjax用ライブラリファイル
	private $pageDefPosition;		// 現在取得しているページ定義のポジション
	private $pageDefRows;			// ページ定義レコード
	private $useHelp = true;		// 標準ヘルプ機能を使用するかどうか
	private $hasScriptCache = false;	// JavaScriptファイルをブラウザにキャッシュさせるかどうか
	private $lateLaunchWidgetList;	// 遅延実行ウィジェットのリスト
	private $latelaunchWidgetParam;		// 遅延実行ウィジェットのパラメータ
	private $viewPositions = array();	// テンプレート上のポジション
	private $updateParentWindow;		// 親ウィンドウを再描画するかどうか
	private $useMootools;				// MootoolsをPrototypeの代わりに使用するかどうか
	private $useScriptaculous;			// scriptaculousを使用するかどうか
	private $headDescription;				// HTMLヘッダ「description」に出力する文字列
	private $headKeywords;				// HTMLヘッダ「keywords」に出力する文字列
	private $headCss = array();					// HTMLヘッダにCSS出力する文字列
	private $outputHead;				// HTMLヘッダ出力を行ったかどうか
	private $libFiles;					// javascript追加用ライブラリ
	const ADMIN_WIDGET_ID = 'admin_main';		// 管理用ウィジェットのウィジェットID
	const WIDGET_ID_TAG_START = '{{WIDGETID:';		// 遅延実行用タグ
	const WIDGET_ID_TAG_END = '}}';		// 遅延実行用タグ
	const WIDGET_ID_SEPARATOR = ',';
	const HEAD_TAG_KEYWORDS		= 	'{{HEAD_KEYWORDS}}';			// HTMLヘッダのkeywords埋め込み用タグ
	const HEAD_TAG_DESCRIPTION	= 	'{{HEAD_DESCRIPTION}}';			// HTMLヘッダのdescription埋め込み用タグ
	const HEAD_TAG_CSS			= 	'{{HEAD_CSS}}';			// HTMLヘッダのCSS埋め込み用タグ
	const WIDGET_ICON_IMG_SIZE = 32;			// ウィジェットアイコンサイズ
	const POSITION_TAG_HEAD = 'm3pos_';			// ポジションの識別用タグIDヘッダ
	const WIDGET_TAG_HEAD = 'm3widget_';			// ウィジェットの識別用タグIDヘッダ
	const WIDTET_CLASS_NAME = 'm3widget';			// ウィジェットオブジェクトのタグクラス名
	const WIDTET_CLASS_TYPE_0 = 'm3widget_type0';			// ウィジェットオブジェクトのタグクラス(ページ共通でない)
	const WIDTET_CLASS_TYPE_1 = 'm3widget_type1';			// ウィジェットオブジェクトのタグクラス(ページ共通)
	const POSITION_CLASS_NAME = 'm3position';		// ポジションオブジェクトのタグクラス名
	// インナーウィジェット用
	const IWIDTET_CMD_CONTENT = 'content';		// コンテンツ取得
	const IWIDTET_CMD_INIT = 'init';			// 初期化
	const IWIDTET_CMD_UPDATE = 'update';		// 更新
	const IWIDTET_CMD_CALC = 'calc';			// 計算
	const DEFAULT_TEMPLATE_CSS_FILE = '/css/template_css.css';		// デフォルトのテンプレートCSSファイル
	const DEFAULT_HELP_SCRIPT_FILE = 'boxover2.1/boxover.js';		// デフォルトのヘルプスクリプトファイル
	// Javascriptライブラリ
	const LIB_JQUERY_EASING		= 'jquery.easing';
	const LIB_JQUERY_JCAROUSEL	= 'jquery.jcarousel';
	// Javascriptライブラリ用のファイル
	const JQUERY_EASING_FILENAME	= 'jquery/jquery.easing.1.3.js';
	const JQUERY_JCAROUSEL_FILENAME	= 'jquery/jquery.jcarousel.pack.js';
	const JQUERY_JCAROUSEL_CSS		= 'jquery/jquery.jcarousel.css';
	// ファイル名
	const PROTOTYPE_FILENAME		= 'prototype.js';						// Prototype
	const MOOTOOLS_FILENAME			= 'mootools-release-1.11.js';			// mootools
	const SCRIPTACULOUS_FILENAME	= 'scriptaculous/scriptaculous.js';			// scriptaculous
	const JQUERY_FILENAME			= 'jquery-1.2.3.min.js';						// JQuery
	const FCKEDITOR_FILENAME		= 'fckeditor2.6/fckeditor.js';		// FCKEditor
	// 設定ファイル
	const FCKEDITOR_CONFIG			= 'm3/fckconfig.js';		// FCKEditor
	//const FCKEDITOR_CONFIG			= 'fckeditor2.6/fckconfig.js';		// FCKEditor
	// Magic3用スクリプト
	const M3_ADMIN_SCRIPT_FILENAME	= 'm3admin1.1.2.js';				// 管理機能用スクリプト
	const M3_STD_SCRIPT_FILENAME	= 'm3std1.1.js';
	const M3_AJAX_SCRIPT_FILENAME	= 'm3ajax1.1.js';
	
	/**
	 * コンストラクタ
	 */
	function __construct()
	{
		global $gInstanceManager;
		global $gEnvManager;
				
		// システムDBオブジェクト取得
		$this->db = $gInstanceManager->getSytemDbObject();
		
		// 共通スクリプトファイル
		// 「ルート/scripts」ディレクトリからの相対パスで指定する
		$this->defaultScriptFiles = array(self::M3_STD_SCRIPT_FILENAME);
		$this->defaultCssFiles = array();
		$this->defaultAdminScriptFiles = array(self::PROTOTYPE_FILENAME,
											self::FCKEDITOR_FILENAME,			// FCKEditor
											self::M3_STD_SCRIPT_FILENAME,
											self::M3_ADMIN_SCRIPT_FILENAME,
											self::M3_AJAX_SCRIPT_FILENAME);
		// デフォルトの設定
		//$this->defaultAdminScriptFiles[] = self::FCKEDITOR_CONFIG;				// FCKEditor
											//'fckeditor/fckeditor.js');		
								//			'mootools-release-1.11.js',			// mootools
								//			'bubble-tooltip/js/bubble-tooltip.js');// Bubble Tooltip
		//$this->defaultAjaxLibFile = self::JQUERY_FILENAME;	// デフォルトのAjax用ライブラリファイル
		
		$this->libFiles = array(self::LIB_JQUERY_EASING => array('script' => array(self::JQUERY_EASING_FILENAME)),		// jquery.easing用のファイル
								self::LIB_JQUERY_JCAROUSEL => array(	'script' => array(self::JQUERY_JCAROUSEL_FILENAME),
																		'css'	=> array(self::JQUERY_JCAROUSEL_CSS)));			// jquery.jcarousel用のファイル
	
		// 遅延ウィジェットリスト									
		$this->lateLaunchWidgetList = array();
		$this->latelaunchWidgetParam = array();
		
		// DB接続可能なときは設定値を取得
		if ($gEnvManager->canUseDb()){
			$value = $this->db->getSystemConfig('script_cache_in_browser');	// ブラウザにJavaScriptファイルのキャッシュを保持するかどうか
			if ($value != '') $this->hasScriptCache = $value;
			
			// ヘッダ出力用
			$this->headDescription = $this->db->getSiteDefValue(M3_TB_FIELD_SITE_DESCRIPTION);	// HTMLヘッダ「description」に出力する文字列
			$this->headKeywords = $this->db->getSiteDefValue(M3_TB_FIELD_SITE_KEYWORDS);		// HTMLヘッダ「keywords」に出力する文字列
		}
	}
	/**
	 * ポップアップメッセージを設定
	 *
	 * @param string $msg   メッセージ
	 */
	function setPopupMsg($msg)
	{
		$this->popupMsg = $msg;
	}
	/**
	 * HTMLヘッダ「description」に出力する文字列を設定
	 *
	 * @param string $str   出力文字列
	 */
	function setHeadDescription($str)
	{
		$this->headDescription = $str;
	}
	/**
	 * HTMLヘッダ「keywords」に出力する文字列を設定
	 *
	 * @param string $str   出力文字列
	 */
	function setHeadKeywords($str)
	{
		$this->headKeywords = $str;
	}
	/**
	 * HTMLヘッダに出力するCSSの文字列を設定
	 *
	 * @param string $css	追加するCSS内容
	 * @return 				なし
	 */
	function addHeadCss($css)
	{
		$this->headCss[] = $css;
	}
	/**
	 * 表示ポジションを表示するかどうか
	 *
	 * @param int $mode   0=ポジション表示しない(通常画面)、1=ポジション表示、2=ウィジェット込みポジション表示
	 */
	function showPosition($mode)
	{
		$this->showPositionMode = $mode;
	}
	/**
	 * ウィジェットの単体表示を設定
	 */
	function showWidget()
	{
		$this->showWidget = true;
	}
	/**
	 * システム制御遷移モードを設定
	 *
	 * @param int $mode   0=設定なし、1=サイト非公開時
	 */
	function setSystemHandleMode($mode)
	{
		$this->systemHandleMode = $mode;
	}
	/**
	 * システム制御遷移モード取得
	 */
	function getSystemHandleMode()
	{
		return $this->systemHandleMode;
	}
	/**
	 * ヘルプ機能の使用可否を設定
	 *
	 * @param bool $status	ヘルプ機能を使用するかどうか
	 * @return 				なし
	 */
	function setUseHelp($status)
	{
		$this->useHelp = $status;
	}
	/**
	 * JavaScriptのブラウザキャッシュの使用可否を設定
	 *
	 * @param bool $status	ブラウザキャッシュを使用するかどうか
	 * @return 				なし
	 */
	function setHasScriptCache($status)
	{
		$this->hasScriptCache = $status;
	}
	/**
	 * MootoolsをPrototypeの代わりに使用するかどうか
	 *
	 * @return 				なし
	 */
	function useMootools()
	{
		$this->useMootools = true;
	}
	/**
	 * scriptaculousを使用するかどうか
	 *
	 * @return 				なし
	 */
	function useScriptaculous()
	{
		$this->useScriptaculous = true;
	}
	/**
	 * 親ウィンドウを再描画
	 *
	 * @return 				なし
	 */
	function updateParentWindow()
	{
		$this->updateParentWindow = true;
	}
	/**
	 * CSSファイルの追加
	 *
	 * @param string $path	追加するファイルのパス(「ルート/scripts」ディレクトリからの相対パスで指定する)
	 * @return 				なし
	 */
	function addCssFile($path)
	{
		$destPath = trim($path, '/');
		if (!in_array($destPath, $this->defaultCssFiles)) $this->defaultCssFiles[] = $destPath;
	}
	/**
	 * JavaScriptファイルの追加
	 *
	 * @param string $path	追加するファイルのパス(「ルート/scripts」ディレクトリからの相対パスで指定する)
	 * @return 				なし
	 */
	function addScriptFile($path)
	{
		$destPath = trim($path, '/');
		if (!in_array($destPath, $this->defaultScriptFiles)) $this->defaultScriptFiles[] = $destPath;
	}
	/**
	 * JavaScriptファイルの追加
	 *
	 * @param string $path	追加するファイルのパス(「ルート/scripts」ディレクトリからの相対パスで指定する)
	 * @return 				なし
	 */
	function addAdminScriptFile($path)
	{
		$destPath = trim($path, '/');
		if (!in_array($destPath, $this->defaultAdminScriptFiles)) $this->defaultAdminScriptFiles[] = $destPath;
	}
	/**
	 * ページ作成開始
	 *
	 * HTTPヘッダを設定する。セッションを取得する。
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 */
	function start($request)
	{
		global $gEnvManager;
		global $gRequestManager;
		global $gInstanceManager;
		global $gAccessManager;
		global $gSystemManager;
		
		// セッション変数を取得可能にする
		session_start();

		if (!defined('M3_STATE_IN_INSTALL')){		// インストール時はセッションの再作成は行わない
			// セッションを再生成する(セキュリティ対策)
			if ($gSystemManager->regenerateSessionId()){
				$gAccessManager->setOldSessionId(session_id());		// 古いセッションIDを保存
				session_regenerate_id(true);
			}
		}

		// ページサブIDを取得
		$subId = $request->trimValueOf(M3_REQUEST_PARAM_PAGE_SUB_ID);
		if (empty($subId)) $subId = $gEnvManager->getDefaultPageSubId();
		$gEnvManager->setCurrentPageSubId($subId);
		
		// セッションからユーザ情報を取得
		$userInfo = $gRequestManager->getSessionValueWithSerialize(M3_SESSION_USER_INFO);
		$gInstanceManager->setUserInfo($userInfo);
	}
	/**
	 * ページ作成終了
	 *
	 * ・最終HTML出力
	 * ・セッション情報の保存
	 * ・ウィジェットで生成されたHTTPヘッダを設定する
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 */
	function end($request)
	{
		global $gAjaxManager;
		global $gRequestManager;
		global $gInstanceManager;

		// 実行コマンドを取得
		$cmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		
		// 最終HTML(ページ全体で使用するHTML)の出力
		if ($cmd != M3_REQUEST_CMD_DO_WIDGET){		// ウィジェット単体オペレーションのときは出力しない
			$this->getLastContents($request);
		}

		// セッションへユーザ情報を保存
		$userInfo = $gInstanceManager->getUserInfo();
		$gRequestManager->setSessionValueWithSerialize(M3_SESSION_USER_INFO, $userInfo);
		
		// キャッシュリミッタは、各リクエスト毎に(アウトプットバッファー が無効な場合は、
		// session_start()がコールされる 前に) session_cache_limiter()をコールする必要がある。
	 	// キャッシュを残す設定
//	 	session_cache_limiter('private');
//	 	session_cache_expire(5);

		// キャッシュを無効にする場合
		header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');// 過去の日付
		header('Cache-Control: no-store, no-cache, must-revalidate');// HTTP/1.1
		header('Cache-Control: post-check=0, pre-check=0', false);
		header('Pragma: no-cache');
		
		// 更新日時
		header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
		
		// Ajax用JSON型データをHTTPヘッダに格納
		$data = $gAjaxManager->header($request);
	}
	/**
	 * 遅延ウィジェット実行
	 *
	 * 遅延実行インデックスのついているウィジェットをインデックス順に実行し、出力バッファデータ内のタグの位置に出力を埋め込む
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @param string         $srcBuf		バッファデータ
	 * @return 								なし
	 */
	function lateLaunchWidget($request, $srcBuf)
	{
		global $gEnvManager;
		global $gDesignManager;
		global $gErrorManager;
		
		// 遅延実行ウィジェットをインデックス順にソート
		asort($this->lateLaunchWidgetList, SORT_NUMERIC);
		
		// タグを置換
		$destBuf = $srcBuf;
		foreach ($this->lateLaunchWidgetList as $widgetId => $value){
			// 実行パラメータ取得
			$count = count($this->latelaunchWidgetParam);
			for ($i = 0; $i < $count; $i++){
				list($wId, $index, $confId, $preId, $serial) = $this->latelaunchWidgetParam[$i];
				if ($wId == $widgetId){
					// バッファ作成
					ob_start();

					// ウィジェット実行ファイル取得
					$widgetIndexFile = $gEnvManager->getWidgetsPath() . '/' . $widgetId . '/index.php';

					// その他パラメータ取得
					$configId = $confId;		// ウィジェット定義ID
					if ($configId == 0) $configId = '';
					$prefix = $preId;		// サフィックス文字列
			
					// ウィジェットの前出力
					echo $gDesignManager->getAdditionalWidgetOutput(true);
				
					// 作業中のウィジェットIDを設定
					$gEnvManager->setCurrentWidgetId($widgetId);

					// ウィジェット定義IDを設定
					$gEnvManager->setCurrentWidgetConfigId($configId);
					
					// ページ定義のシリアル番号を設定
					$gEnvManager->setCurrentPageDefSerial($serial);
		
					// パラメータを設定
					$gEnvManager->setCurrentWidgetPrefix($prefix);		// プレフィックス文字列
		
					// 実行ログを残す
					$this->db->writeWidgetLog($widgetId, 0/*ページ実行*/);
					
					// ウィジェットを実行
					// ウィジェットの呼び出しは、複数回存在する可能性があるのでrequire_once()で呼び出さない
					$msg = 'widget-start(' . $widgetId . ')';
					$gErrorManager->writeDebug(__METHOD__, $msg);		// 時間計測用
					require($widgetIndexFile);
					$msg = 'widget-end(' . $widgetId . ')';
					$gErrorManager->writeDebug(__METHOD__, $msg);		// 時間計測用

					// 作業中のウィジェットIDを解除
					$gEnvManager->setCurrentWidgetId('');
		
					// ウィジェット定義IDを解除
					$gEnvManager->setCurrentWidgetConfigId('');
					
					// ページ定義のシリアル番号を解除
					$gEnvManager->setCurrentPageDefSerial(0);
		
					// パラメータを解除
					$gEnvManager->setCurrentWidgetPrefix('');				// プレフィックス文字列

					// ウィジェットの後出力
					echo $gDesignManager->getAdditionalWidgetOutput(false);
				
					// 現在のバッファ内容を取得し、バッファを破棄
					$srcContents = ob_get_contents();
					ob_end_clean();
					
					// ウィジェットの出力を取得
					$tag = self::WIDGET_ID_TAG_START . $widgetId . self::WIDGET_ID_SEPARATOR . $index . self::WIDGET_ID_TAG_END;
					$destBuf = str_replace($tag, $srcContents, $destBuf);
				}
			}
		}
		// ##### ヘッダ部分の置換 #####
		if ($this->outputHead){				// HTMLヘッダ出力を行っているとき
			// サイトの説明
			if (empty($this->headDescription)){		// 空のときはタグを消去
				$destBuf = str_replace(self::HEAD_TAG_DESCRIPTION, '', $destBuf);
			} else {
				$replaceStr = '<meta name="description" content="' . htmlspecialchars($this->headDescription) . '" />' . M3_NL;
				$destBuf = str_replace(self::HEAD_TAG_DESCRIPTION, $replaceStr, $destBuf);
			}
			// 検索エンジン用キーワード
			if (empty($this->headKeywords)){		// 空のときはタグを消去
				$destBuf = str_replace(self::HEAD_TAG_KEYWORDS, '', $destBuf);
			} else {
				$replaceStr = '<meta name="keywords" content="' . htmlspecialchars($this->headKeywords) . '" />' . M3_NL;
				$destBuf = str_replace(self::HEAD_TAG_KEYWORDS, $replaceStr, $destBuf);
			}
			// HEADタグに埋め込むCSS
			if (count($this->headCss) > 0){
				$replaceStr = '<style type="text/css">' . M3_NL;
				$replaceStr .= '<!--' . M3_NL;
				for ($i = 0; $i < count($this->headCss); $i++){
					$replaceStr .= $this->headCss[$i];
				}
				$replaceStr .= '//-->' . M3_NL;
				$replaceStr .= '</style>' . M3_NL;
				$destBuf = str_replace(self::HEAD_TAG_CSS, $replaceStr, $destBuf);
			} else {// 空のときはタグを消去
				$destBuf = str_replace(self::HEAD_TAG_CSS, '', $destBuf);
			}
		}
		return $destBuf;
	}
	/**
	 * ウィジェット検索モードの場合のページサブIDの設定
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 */
	function redirectToUpdatedPageSubId($request)
	{
		global $gEnvManager;
		
		// 現在設定されているページIDを取得
		$pageId		= $gEnvManager->getCurrentPageId();
		$pageSubId	= $gEnvManager->getCurrentPageSubId();
		
		// 送信元のウィジェットIDを取得
		$fromWidgetId = $request->trimValueOf(M3_REQUEST_PARAM_FROM);
		
		// 対象のウィジェットIDを取得
		$targetWidgetId = $request->trimValueOf(M3_REQUEST_PARAM_WIDGET_ID);
		
		// 対象のウィジェットのページサブIDを取得
		$ret = $this->db->getSubPageId($targetWidgetId, $pageId, $rows);
		if ($ret){// データが存在する
			if (empty($rows[0]['pd_sub_id'])){		// 共通ウィジェットのときは、送信元にあわせる
				$ret = $this->db->getSubPageId($fromWidgetId, $pageId, $rows2);
				if ($ret){// データが存在する
					if (empty($rows2[0]['pd_sub_id'])){		// 送信元が共通ウィジェットのときは、既に設定されているページサブIDを使用
					} else {
						$gEnvManager->setCurrentPageSubId($rows2[0]['pd_sub_id']);
					}
				}
			} else {
				// 送信元があるか順にチェック
				for ($i = 0; $i < count($rows); $i++){
					$ret = $this->db->isExistsWidgetOnPage($pageId, $rows[$i]['pd_sub_id'], $fromWidgetId);
					if ($ret){	
						break;
					}
				}
				if ($i == count($rows)){		// 送信元が見つからない場合は1番目のページサブIDを使用
					$gEnvManager->setCurrentPageSubId($rows[0]['pd_sub_id']);
				} else {
					$gEnvManager->setCurrentPageSubId($rows[$i]['pd_sub_id']);// 存在するときは見つかったページサブIDで更新
				}
			}
		} else {		// 対象のウィジェットが見つからない場合は、互換ウィジェットを探す
			$widgetId = $this->db->getCompatibleWidgetId($targetWidgetId);
			if (!empty($widgetId)){
				$targetWidgetId = $widgetId;
				
				// 対象のウィジェットのページサブIDを取得
				$ret = $this->db->getSubPageId($targetWidgetId, $pageId, $rows);
				if ($ret){// データが存在する
					if (empty($rows[0]['pd_sub_id'])){		// 共通ウィジェットのときは、送信元にあわせる
						$ret = $this->db->getSubPageId($fromWidgetId, $pageId, $rows2);
						if ($ret){// データが存在する
							if (empty($rows2[0]['pd_sub_id'])){		// 送信元が共通ウィジェットのときは、既に設定されているページサブIDを使用
							} else {
								$gEnvManager->setCurrentPageSubId($rows2[0]['pd_sub_id']);
							}
						}
					} else {
						// 送信元があるか順にチェック
						for ($i = 0; $i < count($rows); $i++){
							$ret = $this->db->isExistsWidgetOnPage($pageId, $rows[$i]['pd_sub_id'], $fromWidgetId);
							if ($ret){	
								break;
							}
						}
						if ($i == count($rows)){		// 送信元が見つからない場合は1番目のページサブIDを使用
							$gEnvManager->setCurrentPageSubId($rows[0]['pd_sub_id']);
						} else {
							$gEnvManager->setCurrentPageSubId($rows[$i]['pd_sub_id']);// 存在するときは見つかったページサブIDで更新
						}
					}
				}
			}
		}
		// ページサブIDが見つからないときは、既に設定されている値を使用
		// 既に設定されている値は、URL「sub」パラメータで指定されている値か
		// 設定されていない場合はデフォルトのサブページID
		
		// ********** 指定ページへリダイレクト ***********
		// 実行パラメータ取得
		$todo = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_TODO);
		$this->redirect('?sub=' . $gEnvManager->getCurrentPageSubId() . '&' . $todo);
	}
	/**
	 * 最終HTML出力処理
	 *
	 * テンプレートの出力が完了した後、HTMLとして出力する最後の出力を行う
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 */
	function getLastContents($request)
	{
		global $gEnvManager;

		$pageId		= $gEnvManager->getCurrentPageId();
		$pageSubId	= $gEnvManager->getCurrentPageSubId();
		$cmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		
		if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
			// ウィジェットレイアウト用カーソル
			if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
				echo '<div id="m3WidgetCursor" style="position:absolute; z-index:1;visibility:hidden;"></div>' . M3_NL;// ウィジェット移動用
				echo '<form method="post" name="m3main">' . M3_NL;
				echo '<input type="hidden" name="task" />' . M3_NL;
				echo '<input type="hidden" name="page" value="' . $pageId . '" />' . M3_NL;
				echo '<input type="hidden" name="sub" value="' . $pageSubId . '" />' . M3_NL;
				if (count($this->viewPositions) > 0) $positions = implode($this->viewPositions, ',');
				echo '<input type="hidden" name="positions" value="' . $positions . '" />' . M3_NL;
				echo '<input type="hidden" name="position" />' . M3_NL;
				echo '<input type="hidden" name="widgets" />' . M3_NL;
				echo '<input type="hidden" name="widgetcount" />' . M3_NL;
				echo '<input type="hidden" name="posindex" />' . M3_NL;
				echo '<input type="hidden" name="widgetcommon" />' . M3_NL;
				echo '</form>' . M3_NL;
				echo '<SCRIPT language="JavaScript">' . M3_NL;
				echo '<!--' . M3_NL;
				echo 'function configwidget(widgetId, config, configid, serial){' . M3_NL;
				echo '    if (config == 0){' . M3_NL;
				echo '        alert("このウィジェットには設定画面がありません");' . M3_NL;
				echo '        return false;' . M3_NL;
				echo '    }' . M3_NL;
				$adminUrl = $gEnvManager->getDefaultAdminUrl();		// 管理機能URL
				echo '    window.open("' . $adminUrl . '?cmd=configwidget&openby=other&widget=" + widgetId + "&config=" + config + "&_defconfig=" + configid + "&_defserial=" + serial,"","toolbar=no,menubar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=1050,height=900");' . M3_NL;
				echo '    return false;' . M3_NL;
				echo '}' . M3_NL;
				// イベント処理追加
				echo 'Event.observe(window, "load", function(){' . M3_NL;// ロードイベント処理
				echo 'Event.observe(document, "mousemove", m3MouseMove, false);' . M3_NL;
				echo 'Event.observe(document, "click", m3MouseClick, false);' . M3_NL;
				// ウィジェットDragDrop用のスクリプト
				for ($i = 0; $i < count($this->viewPositions); $i++){
					$posTag = self::POSITION_TAG_HEAD . $this->viewPositions[$i];
					echo 'Sortable.create("' . $posTag . '", { tag:"div", onUpdate:m3UpdateWidgetPosition } );' . M3_NL;
					//echo 'Sortable.create("' . $posTag . '", { tag:"div", onUpdate:m3UpdateWidgetPosition, format:/((.+))/ } );' . M3_NL;
				}
				// その他の読み込み
				/*
				echo 'var contextmenu = [{name: "Back", callback: function(){alert("back function called")}},' . M3_NL;
				echo '                  {name: "Forward", callback: function(){alert("Forward function called")}}]' . M3_NL;
				echo 'new Proto.Menu({' . M3_NL;
				echo '	selector: "widget",' . M3_NL; // context menu will be shown when element with class name of "contextmenu" is clicked
				echo '	className: "widget",' . M3_NL; // this is a class which will be attached to menu container (used for css styling)
				echo '	menuItems: contextmenu' . M3_NL;// array of menu items
				echo '})' . M3_NL;*/
			
				echo 'menu3 = { attributes: "id,common,widgetid,config,configid,serial,menu1",' . M3_NL;
				echo 'items: [' . M3_NL;
				echo '		{type: RightContext.TYPE_MENU,' . M3_NL;
				echo '		text: "ウィジェットの設定",' . M3_NL;
				echo '		onclick: function(){configwidget("[widgetid]", "[config]", "[configid]", "[serial]");} },' . M3_NL;
				echo '		{type: RightContext.TYPE_MENU,' . M3_NL;
				echo '		text: "[menu1]",' . M3_NL;
				echo '		onclick: function(){m3ToggleCommonWidget("[id]", "[widgetid]", "[common]");} },' . M3_NL;
				echo '		{type: RightContext.TYPE_MENU,' . M3_NL;
				echo '		text: "このウィジェットを削除",' . M3_NL;
				echo '		onclick: function(){m3DeleteWidget("[id]", "[widgetid]");} }' . M3_NL;
				echo '	]' . M3_NL;
				echo '};' . M3_NL;
				echo 'RightContext.addMenu("widget", menu3);' . M3_NL;
				echo 'RightContext.initialize();' . M3_NL;
				// 携帯用テンプレートのときは、プレビューウィンドウの更新を通知する
				if ($gEnvManager->getCurrentTemplateType() == 1){
					echo 'if (window.parent.m3UpdateByChildWindow) window.parent.m3UpdateByChildWindow();' . M3_NL;
				}
				echo '});' . M3_NL;// ロードイベント終了
				echo '// -->' . M3_NL;
				echo '</SCRIPT>' . M3_NL;
			}
			// ヘルプシステムの組み込み
			// ヘルプシステムは、「span」タグで埋め込み、「title」属性を使用する
			if ($this->useHelp){			// ヘルプ表示のとき
				$helpScript = $gEnvManager->getScriptsUrl() . '/' . self::DEFAULT_HELP_SCRIPT_FILE;
				echo '<script src="' . $helpScript . '"></script>' . M3_NL;
			} else {			// ヘルプ非表示のときは、title属性をクリアする
				echo '<script type="text/javascript">' . M3_NL;
				echo '<!--' . M3_NL;
				echo 'var elems = document.getElementsByTagName("span");' . M3_NL;
				echo 'for (var i = 0; i < elems.length; i++)' . M3_NL;
				echo '{' . M3_NL;
				echo '    elems[i].title = "";// ツールチップクリア' . M3_NL;
				echo '}' . M3_NL;
				echo '//-->' . M3_NL;
				echo '</script>' . M3_NL;
			}
		} else {		// 通常画面のとき
		}
		// Magic3出力コメント
		echo '<!-- created by Magic3 Framework ' . M3_SYSTEM_VERSION . ' - http://www.magic3.org -->' . M3_NL;
		//echo '<!-- convert time: ' . sprintf('%01.03f', getmicrotime() - M3_MTIME) . ' -->' . M3_NL;
		echo '<!-- convert time: ' . sprintf('%01.03f', microtime(true) - M3_MTIME) . ' -->' . M3_NL;
	}
	/**
	 * Widget単体起動用のHTMLのヘッダ部(headタグ)出力
	 *
	 * Widgetの出力方法は、以下のパターンがある
	 *  ・Widget単体で画面出力するためにHTMLヘッダを付加するパターン
	 *  ・Wiget単体のタグ出力のみのパターン
	 *
	 * @param string $cmd		起動コマンド
	 */
	function startWidget($cmd)
	{
		global $gEnvManager;
		global $gRequestManager;
				
		// ウィジェット単体表示のときのみ出力
		if ($this->showWidget){
			echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' . M3_NL;
			echo '<html>' . M3_NL;
			echo '<head>' . M3_NL;
			
			// HTMLのヘッダ部(headタグ内)出力
			$this->getHeader();
			
			// ウィジェットのJavascriptを読み込む
			$widgetId = $gEnvManager->getCurrentWidgetId();		// カレントのウィジェットID
			
			// テンプレートの設定
			if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET){	// ウィジェット詳細設定画面のとき
				// 管理用テンプレート
				echo '<link href="' . $gEnvManager->getTemplatesUrl() . '/_admin/css/style.css" rel="stylesheet" type="text/css"/>' . M3_NL;
				echo '<!--[if IE]><link rel="stylesheet" type="text/css" media="screen" href="' . $gEnvManager->getTemplatesUrl() . '/_admin/css/iestyles.css"  /><![endif]-->' . M3_NL;
			} else if ($cmd == M3_REQUEST_CMD_SHOW_WIDGET){		// ウィジェットの単体表示のとき
				// ウィジェットが管理用ウィジェットかどうかチェック
				if ($widgetId == self::ADMIN_WIDGET_ID){			// 管理用ウィジェットの場合
					// 管理用テンプレート
					echo '<link href="' . $gEnvManager->getTemplatesUrl() . '/_admin/css/style.css" rel="stylesheet" type="text/css"/>' . M3_NL;
					echo '<!--[if IE]><link rel="stylesheet" type="text/css" media="screen" href="' . $gEnvManager->getTemplatesUrl() . '/_admin/css/iestyles.css"  /><![endif]-->' . M3_NL;
				} else {
					$curTemplate = $this->db->getDefaultTemplateId();
					$templateFile = $gEnvManager->getTemplatesUrl() . '/' . $curTemplate . self::DEFAULT_TEMPLATE_CSS_FILE;
					echo '<link href="' . $templateFile . '" rel="stylesheet" type="text/css"/>' . M3_NL;
				}
			}
			// ウィジェット情報取得
			$ret = $this->db->getWidgetInfo($widgetId, $row);
						
			// スクリプト読み込みが指定されていて、ディレクトリがあるときはディレクトリ内読み込み
			if ($row['wd_read_scripts']){
				$searchPath = $gEnvManager->getWidgetsPath() . '/' . $widgetId . '/' . M3_DIR_NAME_SCRIPTS;
				if (is_dir($searchPath)){
					$dir = dir($searchPath);
					while (($file = $dir->read()) !== false){
						$filePath = $searchPath . '/' . $file;
						if ($file != '.' && $file != '..' && is_file($filePath)){
							// スクリプトへのURLを作成
							$scriptURL = $gEnvManager->getWidgetsUrl() . '/' . $widgetId . '/' . M3_DIR_NAME_SCRIPTS . '/' . $file;
							
							// スクリプトをキャッシュ保存しない場合は、パラメータを付加
							if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
							echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
						}
					}
					$dir->close();
				}
			}
			
			// ウィジェットのタイトルを設定
			$title = $row['wd_name'];
			echo '<title>' . $title . '</title>' . M3_NL;
			echo '</head>' . M3_NL;
			echo '<body>' . M3_NL;
			if ($cmd == M3_REQUEST_CMD_SHOW_WIDGET ||		// ウィジェットの単体表示のとき
				$cmd == M3_REQUEST_CMD_CONFIG_WIDGET){	// ウィジェット詳細設定画面のとき
				// 別ウィンドウで表示のときは、「閉じる」ボタンを表示
				$openBy = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPEN_BY);		// ウィンドウオープンタイプ
				if ($openBy == 'other'){
					echo '<br>' . M3_NL;
					echo '<div align="right"><input type="button" class="button" value="閉じる" onClick="window.close();">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>' . M3_NL;
				}
			}
		//	echo '<br>' . M3_NL;
//			echo '<div align="center">' . M3_NL;
			echo '<!-- Widget Start -->' . M3_NL;
		}
	}
	/**
	 * Widget単体起動用のタグを閉じる
	 *
	 * @param string $cmd		起動コマンド
	 */
	function endWidget($cmd)
	{
		// ウィジェット単体表示のときのみ出力
		if ($this->showWidget){
			echo '<!-- Widget End -->' . M3_NL;
//			echo '</div>' . M3_NL;
			if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET){	// ウィジェット詳細設定画面のとき
				if ($this->updateParentWindow){			// 親ウィンドウ再描画のとき
					echo '<SCRIPT language="JavaScript">' . M3_NL;
					echo '<!--' . M3_NL;
					echo 'Event.observe(window, "load", m3UpdateParentWindow, false);' . M3_NL;
					echo '// -->' . M3_NL;
					echo '</SCRIPT>' . M3_NL;
				}
			}
			echo '</body>' . M3_NL;
			echo '</html>' . M3_NL;
		}
	}
	/**
	 * HTMLのヘッダ部(headタグ内)出力
	 *
	 * システムに共通な定義をHTMLのheadタグ内に出力する
	 * mosFunc.phpからも実行されるので、このメソッドは引数なしに固定。
	 * この関数は、以下の「形式1」または「形式2」でheadタグ内に記述する
	 *
	 * 形式1:            <!-- m3:HTMLHeader -->
	 * 形式2(old style): <?php mosShowHead(); ?>
	 */
	function getHeader()
	{
		global $gEnvManager;
		global $gRequestManager;
		global $database, $option, $my, $mainframe, $_VERSION;
		global $mosConfig_MetaDesc, $mosConfig_MetaKeys, $mosConfig_live_site, $mosConfig_sef, $mosConfig_absolute_path, $mosConfig_sitename, $mosConfig_favicon;
		
		$this->outputHead = true;				// HTMLヘッダ出力を行ったかどうか
		
		// ######### 携帯用サイトの場合は別にヘッダを作成する #########
		if ($gEnvManager->getIsMobile()){
			$this->getMobileHeader();
			return;
		}
		
		// 実行コマンドを取得
		$cmd = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		
		// ********** メタタグの設定 **********
		echo '<meta http-equiv="content-script-type" content="text/javascript">' . M3_NL;
		echo '<meta http-equiv="content-style-type" content="text/css">' . M3_NL;
		
		// キャラクターセット
		echo '<meta http-equiv="content-type" content="text/html; charset=' . M3_HTML_CHARSET .'" />' . M3_NL;
		// 基準ディレクトリの指定
		if ($cmd == M3_REQUEST_CMD_SHOW_POSITION ||				// 表示位置を表示するとき
			$cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){	// 表示位置を表示するとき(ウィジェット付き)
			echo '<base href="' . $gEnvManager->getRootUrl() . '/" />' . M3_NL;
		}
		// ##### 共通ライブラリの読み込み #####
		$this->db->getWidgetsIdWithLib($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId(), $rows);
		for ($i = 0; $i < count($rows); $i++){
			$libArray = explode(',', trim($rows[$i]['wd_add_script_lib']));
			for ($j = 0; $j < count($libArray); $j++){
				$lib = strtolower(trim($libArray[$j]));// 小文字に変換
				if (isset($this->libFiles[$lib])){		// ライブラリが存在するとき
					// JQueryのプラグインの場合はJQueryを追加
					if (strcmp($lib, 'jquery') == 0 || strncmp($lib, 'jquery.', 7) == 0){
						$this->addScriptFile(self::JQUERY_FILENAME);		// JQueryスクリプト追加
					}
					
					if (isset($this->libFiles[$lib]['script'])){
						$scriptFiles = $this->libFiles[$lib]['script'];
						for ($k = 0; $k < count($scriptFiles); $k++){
							$this->addScriptFile($scriptFiles[$k]);		// スクリプト追加
						}
					}
					if (isset($this->libFiles[$lib]['css'])){
						$cssFiles = $this->libFiles[$lib]['css'];
						for ($k = 0; $k < count($cssFiles); $k++){
							$this->addCssFile($cssFiles[$k]);		// CSS追加
						}
					}					
				}
			}
		}

		// ##### 共通CSS読み込み #####
		if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
			// Bubble Tooltip
			//$cssURL = $gEnvManager->getScriptsUrl() . '/bubble-tooltip/css/bubble-tooltip.css';
			//echo '<link rel="stylesheet" href="' . $cssURL . '" media="screen">' . M3_NL;
		}
		// 共通ライブラリのCSSの読み込み
		$count = count($this->defaultCssFiles);
		for ($i = 0; $i < $count; $i++){
			// CSSへのURLを作成
			$cssURL = $gEnvManager->getScriptsUrl() . '/' . $this->defaultCssFiles[$i];
			echo '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
		}
			
		// ##### 表示モードによるCSS読み込み #####
		// ウィジェット付きポジション画面は管理画面のアクセスではない
		if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
			// rightcontext(コンテキストメニューライブラリ)読み込み
			$cssURL = $gEnvManager->getScriptsUrl() . '/rightcontext/rightcontext.css';
			echo '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
			
			// ウィジェット付きポジションのCSS設定
			echo '<style type="text/css">' . M3_NL;
			echo '<!--' . M3_NL;
			echo '.' . self::POSITION_CLASS_NAME . M3_NL;
			echo '{' . M3_NL;
			echo M3_TB . 'font-family: arial, sans-serif;' . M3_NL;
			echo M3_TB . 'font-size: 80%;' . M3_NL;
			echo M3_TB . 'border-collapse: collapse;' . M3_NL;
			echo M3_TB . 'background-color:#eee;' . M3_NL;
			echo M3_TB . 'margin:2px;' . M3_NL;
			echo M3_TB . 'padding:10px;' . M3_NL;
			echo M3_TB . 'border:3px solid #f00;' . M3_NL;
			echo M3_TB . 'color:#700;' . M3_NL;
			echo '}' . M3_NL;
			
			echo '.' . self::WIDTET_CLASS_TYPE_0 . M3_NL;// ウィジェットオブジェクトのタグクラス(ページ共通でない)
			echo '{' . M3_NL;
			echo M3_TB . 'background-color:#ffe4c4;' . M3_NL;
			echo M3_TB . 'margin:2px;' . M3_NL;
			echo M3_TB . 'padding:10px;' . M3_NL;
			echo M3_TB . 'border:2px solid #b22222;' . M3_NL;
			echo M3_TB . 'color:#800000;' . M3_NL;
			echo '}' . M3_NL;
			
			echo '.' . self::WIDTET_CLASS_TYPE_1 . M3_NL;// ウィジェットオブジェクトのタグクラス(ページ共通)
			echo '{' . M3_NL;
			echo M3_TB . 'background-color:#ffe4c4;' . M3_NL;
			echo M3_TB . 'margin:2px;' . M3_NL;
			echo M3_TB . 'padding:10px;' . M3_NL;
			echo M3_TB . 'border:2px solid green;' . M3_NL;
			echo M3_TB . 'color:#800000;' . M3_NL;
			echo '}' . M3_NL;
			echo '-->' . M3_NL;
			echo '</style>' . M3_NL;
		}
			
		// ##### ウィジェットごとのCSS読み込み #####
		// CSSがあるウィジェットを取得
		$this->db->getWidgetsIdWithCss($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId(), $rows);
		for ($i = 0; $i < count($rows); $i++){
			$searchPath = $gEnvManager->getWidgetsPath() . '/' . $rows[$i]['wd_id'] . '/' . M3_DIR_NAME_CSS;
			// ディレクトリがあるときはディレクトリ内読み込み
			if (is_dir($searchPath)){
				$dir = dir($searchPath);
				while (($file = $dir->read()) !== false){
					$filePath = $searchPath . '/' . $file;
					if ($file != '.' && $file != '..' && is_file($filePath)){
						// CSSへのURLを作成
						$cssURL = $gEnvManager->getWidgetsUrl() . '/' . $rows[$i]['wd_id'] . '/' . M3_DIR_NAME_CSS . '/' . $file;
						echo '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
					}
				}
				$dir->close();
			}
		}
		// ##### 共通Javascriptの読み込み #####
		if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
			// ウィジェット付きポジション画面は管理画面のアクセスではない
			if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
				// prototype読み込み
				$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::PROTOTYPE_FILENAME;
				if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
				echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
				
				// wigetのドラッグドロップ用
				$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::M3_ADMIN_SCRIPT_FILENAME;
				if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
				echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
		
				// scriptaculous
				$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::SCRIPTACULOUS_FILENAME;
				if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
				echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
		
				// rightcontext(コンテキストメニューライブラリ)読み込み
				$scriptURL = $gEnvManager->getScriptsUrl() . '/rightcontext/rightcontext.js';
				if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
				echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
			} else {
				// 管理画面用の共通スクリプトを読み込む
				$count = count($this->defaultAdminScriptFiles);
				for ($i = 0; $i < $count; $i++){
					$scriptFilename = $this->defaultAdminScriptFiles[$i];
			
					// PrototypeをMootoolsに変更のとき
					if ($this->useMootools && $scriptFilename == self::PROTOTYPE_FILENAME) $scriptFilename = self::MOOTOOLS_FILENAME;
					$scriptURL = $gEnvManager->getScriptsUrl() . '/' . $scriptFilename;
			
					// スクリプトをキャッシュ保存しない場合は、パラメータを付加
					if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
					echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
				}
				// Scriptaculousファイルの追加
				if ($this->useScriptaculous){
					$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::SCRIPTACULOUS_FILENAME;
								
					// スクリプトをキャッシュ保存しない場合は、パラメータを付加
					if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
					echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
				}
				/*
				if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET){	// ウィジェット詳細設定画面のとき
					// 管理機能用スクリプト
					$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::M3_ADMIN_SCRIPT_FILENAME;
					if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
					echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
				}*/
			}
		} else {			// 通常画面
			// Ajaxライブラリを使用しているウィジェットがあるときは追加
			if ($this->db->isExistsWidgetWithAjax($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId())){
				$this->addScriptFile($this->defaultAjaxLibFile);		// デフォルトAjaxライブラリ追加
				$this->addScriptFile(self::M3_AJAX_SCRIPT_FILENAME);	// Magic3のAjaxライブラリ追加
			}
				
			$count = count($this->defaultScriptFiles);
			for ($i = 0; $i < $count; $i++){
				$scriptURL = $gEnvManager->getScriptsUrl() . '/' . $this->defaultScriptFiles[$i];
			
				// スクリプトをキャッシュ保存しない場合は、パラメータを付加
				if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
				echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
			}
		}
		// ##### ウィジェットごとのJavaScript読み込み #####
		// スクリプトがあるウィジェットを取得
		$this->db->getWidgetsIdWithScript($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId(), $rows);
		for ($i = 0; $i < count($rows); $i++){
			$searchPath = $gEnvManager->getWidgetsPath() . '/' . $rows[$i]['wd_id'] . '/' . M3_DIR_NAME_SCRIPTS;
			
			// ディレクトリがあるときはディレクトリ内読み込み
			if (is_dir($searchPath)){
				$dir = dir($searchPath);
				while (($file = $dir->read()) !== false){
					$filePath = $searchPath . '/' . $file;
					if ($file != '.' && $file != '..' && is_file($filePath)){
						// スクリプトへのURLを作成
						$scriptURL = $gEnvManager->getWidgetsUrl() . '/' . $rows[$i]['wd_id'] . '/' . M3_DIR_NAME_SCRIPTS . '/' . $file;
						// スクリプトをキャッシュ保存しない場合は、パラメータを付加
						if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
						echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
					}
				}
				$dir->close();
			}
		}
		
		// ポップアップメッセージがある場合は表示
		if (!empty($this->popupMsg)){
			echo '<script language="JavaScript">' . M3_NL . '<!--' . M3_NL .  'alert("' . $this->popupMsg . '");' . M3_NL . '// -->' . M3_NL . '</script>';
		}
		// ##### タグ変換用のタグを埋め込む #####
		// ウィジェット単体実行のときはタグを埋め込まない
		if (!$this->showWidget){
			echo self::HEAD_TAG_KEYWORDS;		// HTMLヘッダのkeywords埋め込み用タグ
			echo self::HEAD_TAG_DESCRIPTION;	// HTMLヘッダのdescription埋め込み用タグ
		}
		// 検索ロボットへの指示
		$robots = htmlspecialchars(trim($this->db->getSiteDefValue(M3_TB_FIELD_SITE_ROBOTS)));
		if (!empty($robots)){
			echo '<meta name="robots" content="' . $robots . '" />' . M3_NL;
		}
		
		// サイト構築エンジン
		echo '<meta name="generator" content="' . M3_SYSTEM_NAME . ' ver.' . M3_SYSTEM_VERSION . ' - ' . M3_SYSTEM_DESCRIPTION . '" />' . M3_NL;		

		// favourites icon
		if ( !$mosConfig_favicon ) {
			$mosConfig_favicon = 'favicon.ico';
		}
		$icon = $mosConfig_absolute_path .'/images/'. $mosConfig_favicon;
		// checks to see if file exists
		if ( !file_exists( $icon ) ) {
			$icon = $mosConfig_live_site .'/images/favicon.ico';
		} else {
			$icon = $mosConfig_live_site .'/images/' .$mosConfig_favicon;
		}

		// outputs link tag for page
		echo '<link rel="shortcut icon" href="' . $icon .'" />' . M3_NL;
		
		// ######## 画面タイトル ##########
		// 画面ごとにタイトルを変更する場合はここを修正
		$title = htmlspecialchars(trim($this->db->getSiteDefValue(M3_TB_FIELD_SITE_TITLE)));
		if (!empty($title)){
			echo '<title>' . $title . '</title>' . M3_NL;
		}
		// ##### タグ変換用のタグを埋め込む #####
		// HTMLヘッダのCSS埋め込み用タグ
		if (!$this->showWidget){		// ウィジェット単体実行のときはタグを埋め込まない
			echo self::HEAD_TAG_CSS;			
		}
		// JavaScriptグローバル変数の設定
		echo '<script type="text/javascript">' . M3_NL;
		echo '<!--' . M3_NL;
		echo '// Magic3 Global values' . M3_NL;
		echo 'var M3_ROOT_URL="' . $gEnvManager->getRootUrl() . '";' . M3_NL;		// システムルートURL
		echo '// -->' . M3_NL;
		echo '</script>' . M3_NL;
	}
	/**
	 * 携帯用HTMLのヘッダ部(headタグ内)出力
	 *
	 * @return なし
	 */
	function getMobileHeader()
	{
		global $gEnvManager;
		global $gRequestManager;
		
		// 実行コマンドを取得
		$cmd = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		
		// キャラクターセット
		echo '<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" />' . M3_NL;
		
		// キャッシュを保存させない
		echo '<meta http-equiv="Cache-Control" content="no-cache" />' . M3_NL;
		
		// ##### CSS読み込み #####
		// ウィジェット付きポジション画面は管理画面のアクセスではない
		if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
			// rightcontext(コンテキストメニューライブラリ)読み込み
			$cssURL = $gEnvManager->getScriptsUrl() . '/rightcontext/rightcontext.css';
			echo '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
		}
		
		// ##### javascript読み込み #####
		// ウィジェット付きポジション画面は管理画面のアクセスではない
		if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
			// prototype読み込み
			$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::PROTOTYPE_FILENAME;
			if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
			echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
			
			// wigetのドラッグドロップ用
			$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::M3_ADMIN_SCRIPT_FILENAME;
			if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
			echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
	
			// scriptaculous
			$scriptURL = $gEnvManager->getScriptsUrl() . '/' . self::SCRIPTACULOUS_FILENAME;
			if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
			echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
	
			// rightcontext(コンテキストメニューライブラリ)読み込み
			$scriptURL = $gEnvManager->getScriptsUrl() . '/rightcontext/rightcontext.js';
			if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
			echo '<script language="JavaScript" src="' . $scriptURL . '" type="text/javascript"></script>' . M3_NL;
		}
	}
	/**
	 * 各部品のHTML出力
	 *
	 * @param string $position		HTMLテンプレート上の書き出し位置
	 * @param int    $style			0=ウィジェットを縦に並べる場合, 1=ウィジェットを横に並べる場合, -1=no wrapper
	 */
	function getContents($position, $style = 0)
	{
		global $gRequestManager;
		global $gEnvManager;
		global $gDesignManager;

		// ポジションを保存
		$this->viewPositions[] = $position;
		
		// ファイル名、ページ名を取得
		$filename	= $gEnvManager->getCurrentPageId();
		$subId		= $gEnvManager->getCurrentPageSubId();
		if (empty($subId)) $subId = $gEnvManager->getDefaultPageSubId();

		// ポジション名を表示
		switch ($this->showPositionMode){
			case 0:		// 通常画面
				// ページ定義を取得。同じポジションが続く場合は最初の一度だけ定義を取得
				if (empty($this->pageDefPosition) || $position != $this->pageDefPosition){		// ポジションが異なる場合
					$ret = $this->db->getPageDef($filename, $subId, $position, $rows);
					if ($ret){	// 1行以上データが取得できたとき
						$this->pageDefRows = $rows;			// ページ定義レコード
						$this->pageDefPosition = $position;
					} else {
						$this->pageDefRows = array();
						$this->pageDefPosition = '';
					}
				}
				// ウィジェットを実行
				$count = count($this->pageDefRows);
				for ($i = 0; $i < $count; $i++){
					$this->pageDefLoop($i, $this->pageDefRows[$i]);
				}
			
				if ($position == 'main'){		// メイン部のときは、メッセージを出力
					/*if (strlen($this->popupMsg) > 0){
						echo "\n<script language=\"javascript\">alert('" . addslashes($this->popupMsg) . "');</script>";
					}*/
				} else if ($position == 'debug'){		// デバッグ文出力
				} else {

				}
				break;
			case 1:		// ポジション表示
				echo '<div style="background-color:#eee;margin:2px;padding:10px;border:3px solid #f00;color:#700;">ポジション名: ';
				echo '<b>' . $position . '</b>';
				echo '</div>';
				break;
			case 2:		// ポジション表示(ウィジェット付き)
				$posTag = self::POSITION_TAG_HEAD . $position;
				//echo '<div id="' . $posTag . '" class="' . self::POSITION_CLASS_NAME . '" style="background-color:#eee;margin:2px;padding:10px;border:3px solid #f00;color:#700;">ポジション名: ';
				echo '<div id="' . $posTag . '" class="' . self::POSITION_CLASS_NAME . '" >ポジション名: ';
				echo '<b>' . $position . '</b>';

				// ページ定義を取得。同じポジションが続く場合は最初の一度だけ定義を取得
				if (empty($this->pageDefPosition) || $position != $this->pageDefPosition){		// ポジションが異なる場合
					$ret = $this->db->getPageDef($filename, $subId, $position, $rows);
					if ($ret){	// 1行以上データが取得できたとき
						$this->pageDefRows = $rows;			// ページ定義レコード
						$this->pageDefPosition = $position;
					} else {
						$this->pageDefRows = array();
						$this->pageDefPosition = '';
					}
				}
				// ウィジェットイメージを表示
				$count = count($this->pageDefRows);
				for ($i = 0; $i < $count; $i++){
					$widgetId = $this->pageDefRows[$i]['wd_id'];
					$widgetIndex = $this->pageDefRows[$i]['pd_index'];		// 表示順
					$configId = $this->pageDefRows[$i]['pd_config_id'];		// 定義ID
					$serial = $this->pageDefRows[$i]['pd_serial'];		// シリアル番号
					$widgetTag = self::WIDGET_TAG_HEAD . $position . '_' . $i;
					$image = $gDesignManager->getWidgetIconUrl($widgetId, self::WIDGET_ICON_IMG_SIZE);
					$imageTag = '<img class="' . self::WIDTET_CLASS_NAME . '" src="' . $image . '" ';
					$imageTag .= 'width="' . self::WIDGET_ICON_IMG_SIZE . '"';
					$imageTag .= ' height="' . self::WIDGET_ICON_IMG_SIZE . '"';
					$imageTag .= ' />';
					// 定義名
					if (empty($this->pageDefRows[$i]['pd_config_name'])){
						$configName = '';
					} else {
						$configName = '[' . $this->pageDefRows[$i]['pd_config_name'] . ']';
					}
					// 管理画面
					$hasAdmin = '0';
					if ($this->pageDefRows[$i]['wd_has_admin']){
						$hasAdmin = '1';
					}
					if (empty($this->pageDefRows[$i]['pd_sub_id'])){		// 共通ウィジェットのときは色を変える
						$menuItem1 = 'ページ共通属性を解除';
						//echo '<div id="' . $widgetTag . '" class="' . self::WIDTET_CLASS_NAME . '" ondblclick="m3DoubleClickWidget(event, this, \'' . $widgetId . '\');" style="background-color:#ffe4c4;margin:2px;padding:10px;border:2px solid green;color:#800000;" context="widget" common="1" widgetid="' . $widgetId . '" config="' . $hasAdmin . '" configid="' . $configId . '" serial="' . $serial . '" menu1="' . $menuItem1 . '" >';
						echo '<div id="' . $widgetTag . '" class="' . self::WIDTET_CLASS_TYPE_1 . '" ondblclick="m3DoubleClickWidget(event, this, \'' . $widgetId . '\');" context="widget" common="1" widgetid="' . $widgetId . '" config="' . $hasAdmin . '" configid="' . $configId . '" serial="' . $serial . '" menu1="' . $menuItem1 . '" >';
					} else {
						$menuItem1 = 'ページ共通属性を設定';
						//echo '<div id="' . $widgetTag . '" class="' . self::WIDTET_CLASS_NAME . '" ondblclick="m3DoubleClickWidget(event, this, \'' . $widgetId . '\');" style="background-color:#ffe4c4;margin:2px;padding:10px;border:2px solid #b22222;color:#800000;" context="widget" common="0" widgetid="' . $widgetId . '" config="' . $hasAdmin . '" configid="' . $configId . '" serial="' . $serial . '" menu1="' . $menuItem1 . '" >';
						echo '<div id="' . $widgetTag . '" class="' . self::WIDTET_CLASS_TYPE_0 . '" ondblclick="m3DoubleClickWidget(event, this, \'' . $widgetId . '\');" context="widget" common="0" widgetid="' . $widgetId . '" config="' . $hasAdmin . '" configid="' . $configId . '" serial="' . $serial . '" menu1="' . $menuItem1 . '" >';
					}
					echo '<table class="' . self::WIDTET_CLASS_NAME . '"><tr><td class="' . self::WIDTET_CLASS_NAME . '">' . $imageTag . '</td><td class="' . self::WIDTET_CLASS_NAME . '">';
					echo '<font class="' . self::WIDTET_CLASS_NAME . '" color="#000000">';
					echo '<b class="' . self::WIDTET_CLASS_NAME . '">' . $this->pageDefRows[$i]['wd_name'] . $configName . '</b>';
					echo '<br>';
					echo '(' . $widgetId . ')-' . $widgetIndex;
					echo '</font>';
					echo '</td></tr></table>';
					echo '</div>';
				}
				echo '</div>';
				break;
			default:
				echo '<div style="background-color:#eee;margin:2px;padding:10px;border:1px solid #f00;color:#700;">param error</div>';
				break;
		}
	}
	/**
	 * 各部品のHTML出力
	 *
	 * @param string $position		HTMLテンプレート上の書き出し位置
	 * @return int   				コンテンツの数
	 */
	function getWidgetsCount($position)
	{
		global $gRequestManager;
		global $gEnvManager;

		// 実行コマンドを取得
		$cmd = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
			return 1;		// ウィジェットが設定されていないポジション名を表示するために固定で値を返す
		}
		
		// ファイル名、ページ名を取得
		$filename	= $gEnvManager->getCurrentPageId();
		$subId		= $gEnvManager->getCurrentPageSubId();
		if (empty($subId)) $subId = $gEnvManager->getDefaultPageSubId();

		// 取得しようとするページ定義のポジションが既に取得しているポジションと異なるときはデータを取得
		if (empty($this->pageDefPosition) || $position != $this->pageDefPosition){		// 現在取得しているページ定義のポジション
			$ret = $this->db->getPageDef($filename, $subId, $position, $rows);
			if ($ret){	// 1行以上データが取得できたとき
				$this->pageDefRows = $rows;			// ページ定義レコード
				$this->pageDefPosition = $position;
			} else {
				$this->pageDefRows = array();
				$this->pageDefPosition = '';
			}
		}
		return count($this->pageDefRows);
	}
	/**
	 * 取得した画面定義情報を処理
	 *
	 * @param int $index			行番号
	 * @param array $fetchedRow		fetch取得した行
	 * @param array $param    		任意パラメータ
	 */
	function pageDefLoop($index, $fetchedRow)
	{
		global $gEnvManager;
		global $gDesignManager;
		global $gErrorManager;
//		$style = 1;
		$style = 0;

		// ウィジェットID取得
		$widgetId = $fetchedRow['wd_id'];		
		$widgetIndexFile = $gEnvManager->getWidgetsPath() . '/' . $widgetId . '/index.php';

		// その他パラメータ取得
		$configId = $fetchedRow['pd_config_id'];		// ウィジェット定義ID
		if ($configId == 0) $configId = '';
		$prefix = $fetchedRow['wd_suffix'];		// サフィックス文字列
		$serial = $fetchedRow['pd_serial'];		// シリアル番号
		$lateLaunchIndex = $fetchedRow['wd_launch_index'];		// 遅延実行インデックス
		
		// ウィジェットが遅延実行に指定されている場合は、ウィジェットのタグのみ埋め込む
		if ($lateLaunchIndex > 0){		// 遅延実行のとき
			// 遅延実行ウィジェットリストに追加
			if (!isset($this->lateLaunchWidgetList[$widgetId])){
				$this->lateLaunchWidgetList[$widgetId] = (int)$lateLaunchIndex;
			}
			// 実行パラメータ保存
			$maxNo = 0;		// 最大シリアル番号
			$count = count($this->latelaunchWidgetParam);
			for ($i = 0; $i < $count; $i++){
				list($wId, $index, $confId, $preId, $serial) = $this->latelaunchWidgetParam[$i];
				if ($wId == $widgetId) $maxNo = $index + 1;
			}
			$this->latelaunchWidgetParam[] = array($widgetId, $maxNo, $configId, $prefix, $serial);
			
			// 遅延実行用タグを埋め込む
			echo self::WIDGET_ID_TAG_START . $widgetId . self::WIDGET_ID_SEPARATOR . $maxNo . self::WIDGET_ID_TAG_END;
		} else {
			// ウィジェットが存在する場合は実行
			if (!file_exists($widgetIndexFile)) {
				echo 'widget not found error: ' . $widgetId;
			} else {
				if ($style == 1) {
					echo "<table cellspacing=\"1\" cellpadding=\"0\" border=\"0\" width=\"100%\" " . 'class="moduletable"' . ">\n";
					echo "<tr>\n";
				} else {
				}
				$prepend = ($style == 1) ? "<td valign=\"top\">\n" : '';
				$postpend = ($style == 1) ? "</td>\n" : '';
				echo $prepend;
			
				// ウィジェットの前出力
				echo $gDesignManager->getAdditionalWidgetOutput(true);
				
				// 作業中のウィジェットIDを設定
				$gEnvManager->setCurrentWidgetId($widgetId);
	
				// ウィジェット定義IDを設定
				$gEnvManager->setCurrentWidgetConfigId($configId);
			
				// ページ定義のシリアル番号を設定
				$gEnvManager->setCurrentPageDefSerial($fetchedRow['pd_serial']);
					
				// パラメータを設定
				$gEnvManager->setCurrentWidgetPrefix($prefix);		// プレフィックス文字列
			
				// 実行ログを残す
				$this->db->writeWidgetLog($widgetId, 0/*ページ実行*/);
				
				// ウィジェットを実行
				//require_once($widgetIndexFile);
				// ウィジェットの呼び出しは、複数回存在する可能性があるのでrequire_once()で呼び出さない
				$msg = 'widget-start(' . $widgetId . ')';
				$gErrorManager->writeDebug(__METHOD__, $msg);		// 時間計測用
				require($widgetIndexFile);
				$msg = 'widget-end(' . $widgetId . ')';
				$gErrorManager->writeDebug(__METHOD__, $msg);		// 時間計測用

				// 作業中のウィジェットIDを解除
				$gEnvManager->setCurrentWidgetId('');
			
				// ウィジェット定義IDを解除
				$gEnvManager->setCurrentWidgetConfigId('');
				
				// ページ定義のシリアル番号を解除
				$gEnvManager->setCurrentPageDefSerial(0);
			
				// パラメータを解除
				$gEnvManager->setCurrentWidgetPrefix('');				// プレフィックス文字列

				// ウィジェットの後出力
				echo $gDesignManager->getAdditionalWidgetOutput(false);
//				echo "<!-- ".time()." -->";
				echo $postpend;
				if ($style == 1) {
					echo "</tr>\n</table>\n";
				}
			}
		}
		return true;		// 処理継続
	}
	/**
	 * 画面定義を更新
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 */
	function updatePageDef($request)
	{
		$task = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_TASK);
		if ($task == 'updatepagedef'){
			$pageId		= $request->trimValueOf('page');
			$pageSubId	= $request->trimValueOf('sub');
			$position = $request->trimValueOf('position');
			$widgets = $request->trimValueOf('widgets');
			if (!empty($pageId) && !empty($pageSubId) && !empty($position) && !empty($widgets)){
				$widgetArray = explode(',', $widgets);
			
				// ウィジェットの並び順を変更
				$this->db->orderWidget($pageId, $pageSubId, $position, $widgetArray);
			}
		} else if ($task == 'addwidget'){		// ウィジェットを追加
			$pageId		= $request->trimValueOf('page');
			$pageSubId	= $request->trimValueOf('sub');
			$position = $request->trimValueOf('position');
			$widget = $request->trimValueOf('widgets');
			$index = $request->trimValueOf('posindex');
			if (!empty($pageId) && !empty($pageSubId) && !empty($position) && !empty($widget) && $index >= 0){
				// ウィジェットを追加
				$this->db->addWidget($pageId, $pageSubId, $position, $widget, $index);
			}
		} else if ($task == 'delwidget'){		// ウィジェットを削除
			$pageId		= $request->trimValueOf('page');
			$pageSubId	= $request->trimValueOf('sub');
			$position = $request->trimValueOf('position');
			$widget = $request->trimValueOf('widgets');
			$index = $request->trimValueOf('posindex');
			$widgetCount = $request->trimValueOf('widgetcount');
			if (!empty($pageId) && !empty($pageSubId) && !empty($position) && !empty($widget) && $index >= 0 && !empty($widgetCount)){
				// ウィジェットを削除
				$this->db->delWidget($pageId, $pageSubId, $position, $widget, $index, $widgetCount);
			}
		} else if ($task == 'commonwidget'){		// ウィジェットの共通属性を変更
			$pageId		= $request->trimValueOf('page');
			$pageSubId	= $request->trimValueOf('sub');
			$position = $request->trimValueOf('position');
			$widget = $request->trimValueOf('widgets');
			$index = $request->trimValueOf('posindex');
			$widgetCount = $request->trimValueOf('widgetcount');
			$widgetCommon = $request->trimValueOf('widgetcommon');
			if (!empty($pageId) && !empty($pageSubId) && !empty($position) && !empty($widget) && $index >= 0 && !empty($widgetCount) && ($widgetCommon == '0' || $widgetCommon == '1')){			
				$this->db->toggleCommonWidget($pageId, $pageSubId, $position, $widget, $index, $widgetCount, $widgetCommon);
			}
		}
	}
	/**
	 * インナーウィジェットの操作
	 *
	 * @param int $cmdNo				実行コマンド(0=初期化、1=更新、2=計算、10=コンテンツ取得)
	 * @param string $id				ウィジェットID+インナーウィジェットID
	 * @param string $configId			インナーウィジェット定義ID
	 * @param object $paramObj			インナーウィジェットに渡すパラメータオブジェクト
	 * @param object $optionParamObj	インナーウィジェットに渡すパラメータオブジェクト(オプション)
	 * @param object $resultObj			インナーウィジェットから返る結果オブジェクト
	 * @param string $content			出力内容
	 * @param bool $isAdmin				管理者機能(adminディレクトリ以下)かどうか
	 * @return bool						true=成功、false=失敗
	 */
	function commandIWidget($cmdNo, $id, $configId, &$paramObj, &$optionParamObj, &$resultObj, &$content, $isAdmin = false)
	{
		global $gEnvManager;
		global $gCmdParamManager;
		
		// ウィジェットIDとインナーウィジェットIDを取り出す
		list($widgetId, $iWidgetId) = explode(M3_WIDGET_ID_SEPARATOR, $id);

		// インナーウィジェットに渡すパラメータを設定
		switch ($cmdNo){
			case 0:
				$cmd = self::IWIDTET_CMD_INIT;			// 初期化
				$gCmdParamManager->setParam($id . M3_WIDGET_ID_SEPARATOR . $configId, $cmd, $paramObj, $optionParamObj);
				break;
			case 1:
				$cmd = self::IWIDTET_CMD_UPDATE;		// 更新
				$gCmdParamManager->setParam($id . M3_WIDGET_ID_SEPARATOR . $configId, $cmd);		// 設定されているパラメータの更新は行わない
				break;
			case 2:
				$cmd = self::IWIDTET_CMD_CALC;			// 計算
				$gCmdParamManager->setParam($id . M3_WIDGET_ID_SEPARATOR . $configId, $cmd, $paramObj, $optionParamObj);
				break;
			case 10:
				$cmd = self::IWIDTET_CMD_CONTENT;			// コンテンツ取得
				$gCmdParamManager->setParam($id . M3_WIDGET_ID_SEPARATOR . $configId, $cmd);		// 設定されているパラメータの更新は行わない
				break;
			default:
				$cmd = '';
				$gCmdParamManager->setParam($id . M3_WIDGET_ID_SEPARATOR . $configId, $cmd, $paramObj, $optionParamObj);
				break;
		}

		// インナーウィジェットのエラー出力は呼び出しウィジェット側で受けるため、出力を抑止する
		ob_start();// バッファ作成

		// ウィジェット実行ファイル取得
		if (empty($widgetId)){		// ウィジェットIDが指定されていないときは共通ディレクトリ
		//$gEnvManager->getIWidgetsPath() . '/' . $iWidgetId . '/' . $containerClass . '.php';
		} else {
			if ($isAdmin){
				$widgetIndexFile = $gEnvManager->getWidgetsPath() . '/' . $widgetId . '/include/iwidgets/' . $iWidgetId . '/' . M3_DIR_NAME_ADMIN . '/index.php';
			} else {
				$widgetIndexFile = $gEnvManager->getWidgetsPath() . '/' . $widgetId . '/include/iwidgets/' . $iWidgetId . '/index.php';
			}
		}

		// 作業中のインナーウィジェットIDを設定
		$gEnvManager->setCurrentIWidgetId($id);		// インナーウィジェットを設定

		// インナーウィジェット定義IDを設定
		$gEnvManager->setCurrentIWidgetConfigId($configId);
		
		// ウィジェットを実行
		// ウィジェットの呼び出しは、複数回存在する可能性があるのでrequire_once()で呼び出さない
		if (file_exists($widgetIndexFile)){
			require($widgetIndexFile);
		} else {
			echo 'file not found error: ' . $widgetIndexFile;
		}
		
		// 作業中のウィジェットIDを解除
		$gEnvManager->setCurrentIWidgetId('');
	
		// インナーウィジェット定義IDを解除
		$gEnvManager->setCurrentIWidgetConfigId('');
		
		// 現在のバッファ内容を取得し、バッファを破棄
		$content = ob_get_contents();
		ob_end_clean();
		
		// 値を再取得
		if ($gCmdParamManager->getParam($id . M3_WIDGET_ID_SEPARATOR . $configId, $cmd, $obj, $option)){
			$paramObj = $obj;
			$optionParamObj = $option;
		}

		// 結果を取得
		if ($gCmdParamManager->getResult($id . M3_WIDGET_ID_SEPARATOR . $configId, $resObj)) $resultObj = $resObj;
		return true;
	}
	/**
	 * コールバックメソッドを実行し、出力を返す
	 *
	 * @param array $callback		実行するコールバック
	 * @return string				出力結果
	 */
	function getOutputByCallbackMethod($callback)
	{
		ob_start();// バッファ作成
		
		// コールバック関数を実行
		if (is_callable($callback)) call_user_func($callback);
		
		// 現在のバッファ内容を取得し、バッファを破棄
		$content = ob_get_contents();
		ob_end_clean();
		return $content;
	}
	/**
	 * 指定URLへリダイレクト
	 *
	 * @param string $url			遷移先URL。未指定の場合は現在のスクリプト。URLでないときは、現在のスクリプトに付加。
	 * @return 						なし
	 */
	function redirect($url = '')
	{
		global $gEnvManager;

		$toUrl = $url;
		if (empty($toUrl)){
			$toUrl = $gEnvManager->getCurrentScriptUrl();
		} else if (strncmp($toUrl, 'http://', 7) != 0){
			$toUrl = $gEnvManager->getCurrentScriptUrl() . $toUrl;
		}
		
		ob_end_clean();
		header('HTTP/1.1 301 Moved Permanently');
		header('Location: ' . $toUrl);
//		exit();
	}
	/**
	 * 指定URLのディレクトリへリダイレクト
	 *
	 * @return 						なし
	 */
	function redirectToDirectory()
	{
		global $gEnvManager;

		// ファイル名を削除
		$dirPath = dirname($gEnvManager->getCurrentScriptUrl()) . '/';
		$this->redirect($dirPath);
	}
	/**
	 * インストール用URLへリダイレクト
	 *
	 * @return 						なし
	 */
	function redirectToInstall()
	{
		global $gEnvManager;
		
		$sytemRootUrl = $gEnvManager->calcSystemRootUrl();
		self::redirect($sytemRootUrl . '/admin/install.php');
	}
	/**
	 * ログイン、ログアウト処理を行った後、リダイレクト
	 *
	 * @param RequestManager	$request		HTTPリクエスト処理クラス
	 * @param bool				$success		ログインの成否
	 * @return int								0=何も処理しなかった場合、1=ログイン処理、2=ログアウト処理
	 */
	function standardLoginLogoutRedirect($request, &$success)
	{
		global $gAccessManager;
		
		// ログイン、ログアウト処理、および、コンテナの起動
		$cmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		if ($cmd == M3_REQUEST_CMD_LOGIN){			// ログインの場合
			// ユーザ認証
			if ($gAccessManager->userLogin($request) == true){
				// この画面にリダイレクト
				$this->redirect();
				$success = true;		// ログイン成功
			} else {	// ログイン失敗のとき
				$success = false;		// ログイン失敗
			}
			return 1;
		} else if ($cmd == M3_REQUEST_CMD_LOGOUT){		// ログアウト
			$gAccessManager->userLogout(true);
			
			// この画面にリダイレクト
			$this->redirect();
			return 2;
		} else {
			return 0;
		}
	}
	/**
	 * ウィジェットがセットされているページサブIDを取得
	 *
	 * @param string $pageId		ページID
	 * @param string $widgetId		対象ウィジェットID
	 * @return string				ページサブID
	 */
	function getPageSubIdByWidget($pageId, $widgetId)
	{
		$pageSubId = '';
		
		// 対象のウィジェットのページサブIDを取得
		$ret = $this->db->getSubPageId($widgetId, $pageId, $rows);
		if ($ret){// データが存在する
			if (!empty($rows[0]['pd_sub_id'])) $pageSubId = $rows[0]['pd_sub_id'];
		}
		return $pageSubId;
	}
	/**
	 * ウィジェットが組み込まれているページのURLを生成
	 *
	 * @param string $widgetId	送信元ウィジェットID
	 * @param string $param			実行パラメータ
	 * @return string				生成したURL
	 */
	function getDefaultPageUrlByWidget($widgetId, $param)
	{
		global $gEnvManager;

		// このウィジェットがマップされているページサブIDを取得
		$sub = '';
		$subPageId = $this->getPageSubIdByWidget($gEnvManager->getDefaultPageId(), $widgetId);
		if (empty($subPageId)){
			// 見つからないときは互換ウィジェットを探す
			$targetWidgetId = $this->db->getCompatibleWidgetId($widgetId);
			if (!empty($targetWidgetId)){
				$subPageId = $this->getPageSubIdByWidget($gEnvManager->getDefaultPageId(), $targetWidgetId);
			}
		}
		if (!empty($subPageId)) $sub = 'sub=' . $subPageId . '&';
		return $gEnvManager->getDefaultUrl() . '?' . $sub . $param;
	}
	/**
	 * ウィジェット指定呼び出し用のURLを生成
	 *
	 * @param string $pageId		ページID(空のときは現在のURL)
	 * @param string $toWidgetId	送信先ウィジェットID
	 * @param string $fromWidgetId	送信元ウィジェットID
	 * @param string $todo			実行パラメータ
	 * @return string				生成したURL
	 */
	function createWidgetCmdUrl($pageId, $toWidgetId, $fromWidgetId, $todo)
	{
		global $gEnvManager;
		
		$url = '';
		if (empty($pageId)){	
			$url .= $gEnvManager->getCurrentScriptUrl();
		} else {
			// URLを設定
			$pathArray = explode('_', $pageId);
			for ($i = 0; $i < count($pathArray); $i++){
				$path .= '/' . $pathArray[$i];
			}
			$url = $gEnvManager->getRootUrl() . $path . '.php';
		}
		
		$url .= '?' . M3_REQUEST_PARAM_OPERATION_COMMAND . '=' . M3_REQUEST_CMD_FIND_WIDGET;
		$url .= '&' . M3_REQUEST_PARAM_WIDGET_ID . '=' . $toWidgetId;
		if (!empty($fromWidgetId)) $url .= '&' . M3_REQUEST_PARAM_FROM . '=' . $fromWidgetId;		// 送信元
		if (!empty($todo)) $url .= '&' . M3_REQUEST_PARAM_OPERATION_TODO . '=' . urlencode($todo);
		return $url;
	}
	/**
	 * キャッシュ制御用の付加パラメータを取得
	 *
	 * @return string				パラメータ
	 */	
	function getCacheParam()
	{
		$addParam = '?' . date('YmdHis');
		return $addParam;
	}
	/**
	 * 現在のURLにアクセス可能かチェック
	 *
	 * @return bool				true=可能、false=不可
	 */	
	function canAccessUrl()
	{
		global $gEnvManager;
		
		// 現在設定されているページIDを取得
		$pageId		= $gEnvManager->getCurrentPageId();
		$pageSubId	= $gEnvManager->getCurrentPageSubId();
		return $this->db->canAccessPage($pageId, $pageSubId);
	}
}
?>
