<?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-2012 Magic3 Project.
 * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
 * @version    SVN: $Id: pageManager.php 4740 2012-03-08 04:00:46Z fishbone $
 * @link       http://www.magic3.org
 */
require_once(M3_SYSTEM_INCLUDE_PATH . '/common/core.php');
require_once(M3_SYSTEM_INCLUDE_PATH . '/common/scriptLibInfo.php');

class PageManager extends Core
{
	private $popupMsg;				// ポップアップダイアログメッセージ
	private $showPositionMode;			// ポジション表示モード
	private $showWidget;			// ウィジェットの単体表示
	private $systemHandleMode;			// システム制御遷移モード(1=サイト非公開時)
	private $isPageEditable;		// 一般画面ページ編集可能モード
	private $isTransparentMode;		// 画面透過モード
	private $isEditMode;			// 一般画面編集モード
	private $tmpData;				// データ作成用
	private $db;					// DBオブジェクト
	private $defaultScriptFiles;	// デフォルトで読み込むスクリプトファイル
	private $defaultCssFiles;		// デフォルトで読み込むCSSファイル
	private $defaultAdminScriptFiles;	// デフォルトで読み込むスクリプトファイル(管理用)
	private $defaultAdminCssFiles;		// デフォルトで読み込むCSSファイル(管理用)
	private $headScriptFiles = array();		// ウィジェットからの追加で読み込むスクリプトファイル
	private $headPreMobileScriptFiles = array();// ウィジェットからの追加で読み込むスクリプトファイル(jQueryMobile用挿入ファイル)
	private $headCssFiles = array();		// ウィジェットからの追加で読み込むCSSファイル
	private $headRssFiles = array();		// HTMLヘッダに出力するRSS配信情報
	private $pageDefPosition;		// 現在取得しているページ定義のポジション
	private $pageDefRows;			// ページ定義レコード
	private $nonSharedWidgetCount = -1;	// 非共通ウィジェットの数(-1=ページ作成でないとき)
	private $replaceHeadDone;			// ヘッダマクロ変換処理が完了したかどうか
	private $useHelp = false;		// 標準ヘルプ機能を使用するかどうか
	private $hasScriptCache = false;	// JavaScriptファイルをブラウザにキャッシュさせるかどうか
	private $lateLaunchWidgetList;	// 遅延実行ウィジェットのリスト
	private $latelaunchWidgetParam;		// 遅延実行ウィジェットのパラメータ
	private $viewPositions = array();	// テンプレート上のポジション
	private $viewPosId = array();		// テンプレート上のポジションのタグID
	private $updateParentWindow;		// 親ウィンドウを再描画するかどうか
	private $updateDefSerial;			// 更新する項目のページ定義シリアル番号
	private $headDescription;				// HTMLヘッダ「description」に出力する文字列
	private $headKeywords;				// HTMLヘッダ「keywords」に出力する文字列
	private $lastHeadTitle;				// 最後にヘッダ部titleにセットした文字列
	private $lastHeadDescription;		// 最後にヘッダ部descriptionにセットした文字列
	private $lastHeadKeywords;			// 最後にヘッダ部keywordsにセットした文字列
	private $headCss = array();			// HTMLヘッダにCSS出力する文字列
	private $headScript = array();		// HTMLヘッダにJavascript出力する文字列
	private $headPreMobileScript = array();		// HTMLヘッダにJavascript出力する文字列(jQueryMobile用挿入スクリプト)
	private $headString = array();		// HTMLヘッダに出力する任意文字列
	private $lastHeadCss;				// 最後に設定したHTMLヘッダにCSS出力する文字列
	private $lastHeadScript;			// 最後に設定したHTMLヘッダにJavascript出力する文字列
	private $lastHeadString;			// 最後に設定したHTMLヘッダに出力する任意文字列
	private $initScript = '';				// ウィンドウ初期化時に実行されるスクリプト
	private $outputByHtml = true;				// HTMLフォーマットで出力するかどうか
	private $outputHead;				// HTMLヘッダ出力を行ったかどうか
	private $isAbort;					// ページ作成処理を中断するかどうか
	private $isRedirect;				// リダイレクトするかどうか
	private $libFiles;					// javascript追加用ライブラリ
	private $pageDefRev = 234;				// 画面定義のリビジョン番号
	private $headSubTitle = array();				// ヘッダタグサブタイトル
	private $headSubTitleUrl = array();				// ヘッダサブタイトルのリンク先
	private $pageInfo;					// すべてのページ情報
	private $currentPageInfo;			// 現在のページのページ情報
	private $contentType = '';				// ページのコンテンツタイプ
	private $rssVersion;					// RSSバージョン
	private $rssChannel;				// RSSチャンネルデータ
	private $selectedJQueryFilename;		// 使用対象のjQueryファイル
	private $selectedJQueryUiFilename;		// 使用対象のjQuery UIファイル
	private $selectedJQueryMobileFilename;		// 使用対象のjQueryMobileファイル
	private $urlParamOrder;					// URLパラメータの並び順
	const CONFIG_KEY_HEAD_TITLE_FORMAT = 'head_title_format';		// ヘッダ作成用フォーマット
	const ADMIN_WIDGET_ID = 'admin_main';		// 管理用ウィジェットのウィジェットID
	//const CONTENT_TYPE_WIKI = 'wiki';		// ページのコンテンツタイプ(Wiki)
	const WIDGET_ID_TAG_START = '{{WIDGETID:';		// 遅延実行用タグ
	const WIDGET_ID_TAG_END = '}}';		// 遅延実行用タグ
	const WIDGET_ID_TITLE_TAG_START = '{{WIDGETID_TITLE:';		// 遅延実行用タグ(タイトル埋め込み用)
	const WIDGET_ID_TITLE_TAG_END = '}}';						// 遅延実行用タグ(タイトル埋め込み用)
	const WIDGET_ID_SEPARATOR = ',';
	const HEAD_TAGS				= '{{HEAD_TAGS}}';				// HTMLヘッダ出力用タグ
	const WIDGET_ICON_IMG_SIZE = 32;			// ウィジェットアイコンサイズ
	const POSITION_TAG_HEAD = 'm3pos_';			// ポジションの識別用タグIDヘッダ
	const WIDGET_TAG_HEAD = 'm3widget_';			// ウィジェットの識別用タグIDヘッダ
	const WIDGET_TAG_HEAD_SHORT = 'm3_';			// ウィジェットの識別用タグIDヘッダ
	const WIDGET_TYPE_TAG_HEAD = 'm3widgettype_';			// ウィジェット種別の識別用タグ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 JOOMLA10_DEFAULT_WIDGET_MENU_PARAM = 'class="moduletable"';	// Joomla!1.0用デフォルトメニューパラメータ値
	const ADMIN_TEMPLATE = '_admin';		// PC管理用テンプレートID
	const M_ADMIN_TEMPLATE = 'm/_admin';	// 携帯用管理画面テンプレートID
	const SCRIPT_LIB_SEPARATOR = ';';			// JavaScriptライブラリ読み込み設定のライブラリの区切り
	const PAGE_ID_SEPARATOR = ',';				// ページIDとページサブID連結用
	const DEFAULT_ADMIN_FAVICON_FILE = '/images/system/favicon.ico';			// デフォルトの管理画面用faviconファイル
	const DEFAULT_FAVICON_FILE = '/favicon.ico';			// デフォルトのfaviconファイル
	const DEFAULT_SITE_NAME = 'サイト名未設定';		// 管理画面用のデフォルトサイト名
	const DEFAULT_ADMIN_TITLE = '管理画面';			// デフォルトの管理画面名
	const DEFAULT_RSS_VERSION = '1.0';				// デフォルトのRSSのバージョン
	const CF_USE_LATEST_SCRIPT_LIB = 'dev_use_latest_script_lib';		// 最新のJavaScriptライブラリを使用するかどうか
	const CF_GOOGLE_MAPS_KEY = 'google_maps_key';				// Googleマップ利用キー
	const CF_CONFIG_WINDOW_OPEN_TYPE = 'config_window_open_type';		// ウィジェット設定画面のウィンドウ表示タイプ(0=別ウィンドウ、1=タブ)
	const DEFAULT_THEME_DIR = '/ui/themes/';				// jQueryUIテーマ格納ディレクトリ
	const THEME_CSS_FILE = 'jquery-ui.custom.css';		// テーマファイル
	const CONFIG_ICON_FILE = '/images/system/config.png';			// ウィジェット定義画面アイコン
	const ADJUST_ICON_FILE = '/images/system/adjust_widget.png';	// 位置調整アイコン
	const NOTICE_ICON_FILE = '/images/system/notice16.png';		// ウィジェット配置注意アイコン
	const ADMIN_ICON_FILE = '/images/system/admin64.png';		// パネルメニュー管理画面遷移用アイコン
	const LOGOUT_ICON_FILE = '/images/system/logout64.png';		// パネルメニューログアウト用アイコン
	const EDIT_PAGE_ICON_FILE = '/images/system/create_page64.png';		// パネルメニュー編集用アイコン
	const EDIT_END_ICON_FILE = '/images/system/close64.png';		// パネルメニュー編集終了用アイコン
	
	// アドオンオブジェクト用
	const BLOG_OBJ_ID = 'bloglib';		// ブログオブジェクトID
	
	// インナーウィジェット用
	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';		// デフォルトのヘルプスクリプトファイル
	
	// Magic3用スクリプト
	//const M3_ADMIN_SCRIPT_FILENAME			= 'm3admin1.2.1.js';				// 管理機能用スクリプト
	const M3_ADMIN_SCRIPT_FILENAME			= 'm3admin1.5.5.js';				// 管理機能用スクリプト(FCKEditor2.6.6対応)
	//const M3_ADMIN_WIDGET_SCRIPT_FILENAME	= 'm3admin_widget1.4.0.js';	// 管理機能(ウィジェット操作)用スクリプト
	const M3_ADMIN_WIDGET_SCRIPT_FILENAME	= 'm3admin_widget1.5.1.js';	// 管理機能(ウィジェット操作)用スクリプト(Magic3 v1.15.0以降)
	const M3_ADMIN_WIDGET_CSS_FILE			= '/m3/widget.css';			// 管理機能(ウィジェット操作)用CSSファイル
	const M3_STD_SCRIPT_FILENAME			= 'm3std1.4.1.js';			// 一般、管理機能共通スクリプト
	//const M3_PLUS_SCRIPT_FILENAME			= 'm3plus1.0.0.js';			// 一般画面追加用スクリプト
	const M3_PLUS_SCRIPT_FILENAME			= 'm3plus1.5.0.js';			// 一般画面追加用スクリプト(FCKEditor2.6.6対応)
	const M3_OPTION_SCRIPT_FILENAME			= 'm3opt1.1.0.js';			// AJAXを含んだオプションライブラリファイル(jQuery必須)
	const M3_ADMIN_CSS_FILE					= '/m3/admin.css';			// 管理機能用のCSS
	const M3_EDIT_CSS_FILE					= '/m3/edit.css';			// 一般画面編集用のCSS
	
	/**
	 * コンストラクタ
	 */
	function __construct()
	{
		global $gInstanceManager;
		global $gEnvManager;
		global $gSystemManager;
				
		// 親クラスを呼び出す
		parent::__construct();
		
		// システムDBオブジェクト取得
		$this->db = $gInstanceManager->getSytemDbObject();
		
		// 共通スクリプトファイル
		// 「ルート/scripts」ディレクトリからの相対パスで指定する
		$this->defaultScriptFiles = array(self::M3_STD_SCRIPT_FILENAME);
		$this->defaultCssFiles = array();
		
		// jQueryのバージョンを設定
		if (version_compare(M3_SYSTEM_VERSION, '1.15.0') >= 0){			// jQuery v1.4対応版
			ScriptLibInfo::setJQueryVer(1);
		} else {
			ScriptLibInfo::setJQueryVer(0);			// jQuery v1.2.6対応版
		}
		
		// jQueryファイル名取得
		$this->selectedJQueryFilename = ScriptLibInfo::getJQueryFilename(0);			// 使用対象のjQueryファイル
		$this->selectedJQueryUiFilename = ScriptLibInfo::getJQueryFilename(1);		// 使用対象のjQuery UIファイル
			
		// 管理機能用Javascript取得
		$this->defaultAdminScriptFiles = array($this->selectedJQueryFilename,			// jQuery
											$this->selectedJQueryUiFilename,				// jQuery UI Core
											ScriptLibInfo::getJQueryFilename(2),		// jQuery UI Plus
											ScriptLibInfo::JQUERY_JSHOTKEYS_FILENAME,		// jquery.js-hotkeys
											ScriptLibInfo::JQUERY_CONTEXTMENU_FILENAME,		// jQuery Contextmenu Lib
											self::M3_STD_SCRIPT_FILENAME,
											self::M3_ADMIN_SCRIPT_FILENAME,
											self::M3_OPTION_SCRIPT_FILENAME);
	/*	$value = $gSystemManager->getSystemConfig(self::CF_USE_LATEST_SCRIPT_LIB);// 最新のJavaScriptライブラリを使用するかどうか
		if (empty($value)){				// 最新ライブラリを使用しない
			$this->defaultAdminScriptFiles = array(ScriptLibInfo::JQUERY_FILENAME,			// jQuery
												ScriptLibInfo::JQUERY_UI_CORE_FILENAME,		// jQuery UI Core(Core+Interaction)
												ScriptLibInfo::JQUERY_JSHOTKEYS_FILENAME,		// jquery.js-hotkeys
												ScriptLibInfo::JQUERY_CONTEXTMENU_FILENAME,		// jQuery Contextmenu Lib
												self::M3_STD_SCRIPT_FILENAME,
												self::M3_ADMIN_SCRIPT_FILENAME,
												self::M3_OPTION_SCRIPT_FILENAME);
		} else {		// 最新ライブラリを使用
			$this->defaultAdminScriptFiles = array(ScriptLibInfo::JQUERY_L_FILENAME,			// jQuery
												ScriptLibInfo::JQUERY_L_UI_CORE_FILENAME,		// jQuery UI Core
												ScriptLibInfo::JQUERY_JSHOTKEYS_FILENAME,		// jquery.js-hotkeys
												ScriptLibInfo::JQUERY_CONTEXTMENU_FILENAME,		// jQuery Contextmenu Lib
												self::M3_STD_SCRIPT_FILENAME,
												self::M3_ADMIN_SCRIPT_FILENAME,
												self::M3_OPTION_SCRIPT_FILENAME);
		}*/
		
		$this->defaultAdminCssFiles = array(self::M3_ADMIN_CSS_FILE);			// 管理機能用のCSS
		
		// Javascriptライブラリ
		$this->libFiles = ScriptLibInfo::getLib();			// ライブラリ取得

		// 遅延ウィジェットリスト									
		$this->lateLaunchWidgetList = array();
		$this->latelaunchWidgetParam = array();
		
		// DB接続可能なときは設定値を取得
		if ($gEnvManager->canUseDb()){
			$value = $this->gSystem->getSystemConfig('script_cache_in_browser');	// ブラウザにJavaScriptファイルのキャッシュを保持するかどうか
			if ($value != '') $this->hasScriptCache = $value;
			
			// ヘッダ出力用
			$this->headDescription = $this->gSystem->getSiteDef(M3_TB_FIELD_SITE_DESCRIPTION);	// HTMLヘッダ「description」に出力する文字列
			$this->headKeywords = $this->gSystem->getSiteDef(M3_TB_FIELD_SITE_KEYWORDS);		// HTMLヘッダ「keywords」に出力する文字列
		}
		
		$this->rssVersion = self::DEFAULT_RSS_VERSION;					// RSSバージョン
		
		// URLパラメータ並び順
		$this->urlParamOrder = array(
			// コンテンツID
			M3_REQUEST_PARAM_CONTENT_ID				=> -20,		// 汎用コンテンツID
			M3_REQUEST_PARAM_CONTENT_ID_SHORT		=> -19,		// 汎用コンテンツID(略式)
			M3_REQUEST_PARAM_PRODUCT_ID				=> -18,		// 製品ID
			M3_REQUEST_PARAM_PRODUCT_ID_SHORT		=> -17,		// 製品ID(略式)
			M3_REQUEST_PARAM_BLOG_ID				=> -16,		// ブログID
			M3_REQUEST_PARAM_BLOG_ID_SHORT			=> -15,		// ブログID(略式)
			M3_REQUEST_PARAM_BLOG_ENTRY_ID			=> -14,		// ブログ記事ID
			M3_REQUEST_PARAM_BLOG_ENTRY_ID_SHORT	=> -13,		// ブログ記事ID(略式)
			M3_REQUEST_PARAM_BBS_ID					=> -12,		// 掲示板投稿記事ID
			M3_REQUEST_PARAM_BBS_ID_SHORT			=> -11,		// 掲示板投稿記事ID(略式)
			M3_REQUEST_PARAM_BBS_THREAD_ID			=> -10,		// 掲示板投稿スレッドID
			M3_REQUEST_PARAM_BBS_THREAD_ID_SHORT	=> -9,		// 掲示板投稿スレッドID(略式)
			M3_REQUEST_PARAM_USER_ID				=> -8,		// ユーザ作成コンテンツID
			M3_REQUEST_PARAM_USER_ID_SHORT			=> -7,		// ユーザ作成コンテンツID(略式)
			M3_REQUEST_PARAM_ROOM_ID				=> -6,		// ユーザ作成コンテンツ区画ID
			M3_REQUEST_PARAM_ROOM_ID_SHORT			=> -5,		// ユーザ作成コンテンツ区画ID(略式)
			M3_REQUEST_PARAM_EVENT_ID				=> -4,		// イベントID
			M3_REQUEST_PARAM_EVENT_ID_SHORT			=> -3,		// イベントID(略式)
			M3_REQUEST_PARAM_PHOTO_ID				=> -2,		// 画像ID
			M3_REQUEST_PARAM_PHOTO_ID_SHORT			=> -1,		// 画像ID(略式)
			// URLパラメータ
			M3_REQUEST_PARAM_PAGE_SUB_ID			=> 1,		// ページサブID
			M3_REQUEST_PARAM_PAGE_CONTENT_ID		=> 2,		// ページコンテンツID
			M3_REQUEST_PARAM_WIDGET_ID 				=> 3,		// ウィジェットID
			M3_REQUEST_PARAM_TEMPLATE_ID			=> 4,		// テンプレートID
			M3_REQUEST_PARAM_URL					=> 5,		// リンク先等のURL
			M3_REQUEST_PARAM_STAMP					=> 6,		// 公開発行ID
			M3_REQUEST_PARAM_OPTION					=> 7,		// 通信オプション
			M3_REQUEST_PARAM_OPERATION_COMMAND		=> 8,		// 実行処理
			M3_REQUEST_PARAM_OPERATION_WIKI_COMMAND	=> 9,		// Wikiコマンド実行
			M3_REQUEST_PARAM_OPERATION_TASK			=> 10,		// ウィジェット間共通処理
			M3_REQUEST_PARAM_OPERATION_ACT			=> 11,		// クライアントからの実行処理
			M3_REQUEST_PARAM_OPERATION_LANG			=> 12,		// 言語指定表示
			M3_REQUEST_PARAM_SERIAL_NO				=> 13,		// シリアル番号
			M3_REQUEST_PARAM_PAGE_NO      			=> 14,		// ページ番号
			M3_REQUEST_PARAM_LIST_NO				=> 15,		// 一覧番号
			M3_REQUEST_PARAM_ITEM_NO	      		=> 16,		// 項目番号
			M3_REQUEST_PARAM_OPERATION_TODO			=> 17,		// 指定ウィジェットに実行させる処理
			M3_REQUEST_PARAM_FROM					=> 18,		// メッセージの送信元ウィジェットID
			M3_REQUEST_PARAM_VIEW_STYLE				=> 19,		// 表示スタイル
			M3_REQUEST_PARAM_FORWARD				=> 20,		// 画面遷移用パラメータ
			M3_REQUEST_PARAM_ADMIN_KEY				=> 21,		// 管理者一時キー
			M3_REQUEST_PARAM_OPEN_BY				=> 22,		// ウィンドウの開き方
			M3_REQUEST_PARAM_SHOW_HEADER			=> 23,		// ヘッダ部表示制御
			M3_REQUEST_PARAM_SHOW_FOOTER			=> 24,		// フッタ部表示制御
			M3_REQUEST_PARAM_SHOW_MENU				=> 25,		// メニュー部表示制御
			M3_REQUEST_PARAM_KEYWORD				=> 26,		// 検索キーワード
			M3_REQUEST_PARAM_HISTORY				=> 27,		// 履歴インデックスNo
			M3_REQUEST_PARAM_DEF_PAGE_ID			=> 28,		// ページID(画面編集用)
			M3_REQUEST_PARAM_DEF_PAGE_SUB_ID		=> 29,		// ページサブID(画面編集用)
			M3_REQUEST_PARAM_PAGE_DEF_SERIAL		=> 30,		// ページ定義のレコードシリアル番号(設定画面起動時)
			M3_REQUEST_PARAM_PAGE_DEF_CONFIG_ID		=> 31,		// ページ定義のウィジェット定義ID(設定画面起動時)
			M3_REQUEST_PARAM_BACK_URL				=> 32,		// 戻り先URL
			M3_REQUEST_PARAM_BACKUP_URL				=> 33,		// URL退避用(画面編集時)
			M3_REQUEST_PARAM_SERVER					=> 34,		// サーバ指定
			M3_REQUEST_PARAM_CATEGORY_ID			=> 35);		// カテゴリID(共通)
	}
	/**
	 * タイムアウトを停止
	 *
	 * @return なし
	 */
	function setNoTimeout()
	{
		if (ini_get('safe_mode') == '0') set_time_limit(0);
	}
	/**
	 * ポップアップメッセージを設定
	 *
	 * @param string $msg   メッセージ
	 */
	function setPopupMsg($msg)
	{
		$this->popupMsg = $msg;
	}
	/**
	 * HTMLヘッダ「description」に出力する文字列を設定
	 *
	 * @param string $str   出力文字列
	 */
	function setHeadDescription($str)
	{
		if (is_string($str) && !empty($str)){
			$this->headDescription = $str;
			$this->lastHeadDescription = $str;	// 最後に設定した値を退避
		}
	}
	/**
	 * HTMLヘッダ「description」に出力する文字列を取得
	 *
	 * @return string $str   出力文字列
	 */
	function getHeadDescription()
	{
		return $this->headDescription;
	}
	/**
	 * HTMLヘッダ「keywords」に出力する文字列を設定
	 *
	 * @param string $str   出力文字列
	 */
	function setHeadKeywords($str)
	{
		if (is_string($str) && !empty($str)){
			$this->headKeywords = $str;
			$this->lastHeadKeywords = $str;		// 最後に設定した値を退避
		}
	}
	/**
	 * HTMLヘッダ「keywords」に出力する文字列を取得
	 *
	 * @return string $str   出力文字列
	 */
	function getHeadKeywords()
	{
		return $this->headKeywords;
	}
	/**
	 * HTMLヘッダ「title」のサブタイトル出力する文字列を設定
	 *
	 * @param string $str   出力文字列
	 * @param string $url   リンク先
	 */
	function setHeadSubTitle($str, $url='')
	{
		if (is_string($str) && !empty($str)){
			$this->headSubTitle[] = $str;
			$this->headSubTitleUrl[] = $url;
			$this->lastHeadTitle = $str;	// 最後に設定した値を退避
		}
	}
	/**
	 * HTMLヘッダ「title」のサブタイトル出力する文字列を取得
	 *
	 * @return $array   サブタイトルに設定されている文字列を連想配列(title=タイトル、url=リンク先URL)の配列で返す
	 */
	function getHeadSubTitle()
	{
		$titleArray = array();
		$titleCount = count($this->headSubTitle);
		for ($i = 0; $i < $titleCount; $i++){
			$line = array('title' => $this->headSubTitle[$i], 'url' => $this->headSubTitleUrl[$i]);
			$titleArray[] = $line;
		}
		return $titleArray;
	}
	/**
	 * HTMLヘッダに出力するCSSの文字列を設定
	 *
	 * @param string $css	追加するCSS内容
	 * @return 				なし
	 */
	function addHeadCss($css)
	{
		$destCss = trim($css);
		if (!empty($destCss)){
			if (!in_array($css, $this->headCss)) $this->headCss[] = $css;
			
			$this->lastHeadCss = $css;			// 最後に設定したHTMLヘッダにCSS出力する文字列
		}
	}
	/**
	 * HTMLヘッダに出力するJavascriptの文字列を設定
	 *
	 * @param string $script	追加するJavascript内容
	 * @return 					なし
	 */
	function addHeadScript($script)
	{
		$destScript = trim($script);
		if (!empty($destScript)){
			if (!in_array($script, $this->headScript)) $this->headScript[] = $script;
			
			$this->lastHeadScript = $script;			// 最後に設定したHTMLヘッダにJavascript出力する文字列
		}
	}
	/**
	 * HTMLヘッダに出力するJavascriptの文字列(jQueryMobile用挿入スクリプト)を設定
	 *
	 * @param string $script	追加するJavascript内容
	 * @return 					なし
	 */
	function addHeadPreMobileScript($script)
	{
		$destScript = trim($script);
		if (!empty($destScript)){
			if (!in_array($script, $this->headPreMobileScript)) $this->headPreMobileScript[] = $script;
		}
	}
	/**
	 * HTMLヘッダに出力する任意文字列を設定
	 *
	 * @param string $str	追加する任意文字列
	 * @return 				なし
	 */
	function addHeadString($str)
	{
		$destScript = trim($str);
		if (!empty($destScript)){
			if (!in_array($str, $this->headString)) $this->headString[] = $str;
			
			$this->lastHeadString = $str;			// 最後に設定したHTMLヘッダに出力する任意文字列
		}
	}
	/**
	 * HTMLヘッダに出力するCSSファイルを追加
	 *
	 * @param string,array $cssFile	CSSファイルURLパス
	 * @return 				なし
	 */
	function addHeadCssFile($cssFile)
	{
		if (is_array($cssFile)){	// 配列の場合
			for ($i = 0; $i < count($cssFile); $i++){
				$destCss = trim($cssFile[$i]);
				if (!empty($destCss) && !in_array($destCss, $this->headCssFiles)) $this->headCssFiles[] = $destCss;
			}
		} else {		// 文字列の場合
			$destCss = trim($cssFile);
			if (!empty($destCss) && !in_array($destCss, $this->headCssFiles)) $this->headCssFiles[] = $destCss;
		}
	}
	/**
	 * HTMLヘッダに出力するJavascriptライブラリを追加
	 *
	 * @param string,array $scriptLib	JavascriptライブラリID
	 * @return 					なし
	 */
	function addHeadScriptLib($scriptLib)
	{
		if (is_array($scriptLib)){	// 配列の場合
			for ($i = 0; $i < count($scriptLib); $i++){
				$destScript = trim($scriptLib[$i]);
				if (!empty($destScript)) $this->addScript('', $destScript);// スクリプト追加
			}
		} else {		// 文字列の場合
			$destScript = trim($scriptLib);
			if (!empty($destScript)) $this->addScript('', $destScript);// スクリプト追加
		}
	}
	/**
	 * HTMLヘッダに出力するJavascriptファイルを追加
	 *
	 * @param string,array $scriptFile	JavascriptファイルURLパス
	 * @return 					なし
	 */
	function addHeadScriptFile($scriptFile)
	{
		if (is_array($scriptFile)){	// 配列の場合
			for ($i = 0; $i < count($scriptFile); $i++){
				$destScript = trim($scriptFile[$i]);
				if (!empty($destScript) && !in_array($destScript, $this->headScriptFiles)) $this->headScriptFiles[] = $destScript;
			}
		} else {		// 文字列の場合
			$destScript = trim($scriptFile);
			if (!empty($destScript) && !in_array($destScript, $this->headScriptFiles)) $this->headScriptFiles[] = $destScript;
		}
	}
	/**
	 * HTMLヘッダに出力するJavascriptファイル(jQueryMobile用挿入ファイル)を追加
	 *
	 * @param string,array $scriptFile	JavascriptファイルURLパス
	 * @return 					なし
	 */
	function addHeadPreMobileScriptFile($scriptFile)
	{
		if (is_array($scriptFile)){	// 配列の場合
			for ($i = 0; $i < count($scriptFile); $i++){
				$destScript = trim($scriptFile[$i]);
				if (!empty($destScript) && !in_array($destScript, $this->headPreMobileScriptFiles)) $this->headPreMobileScriptFiles[] = $destScript;
			}
		} else {		// 文字列の場合
			$destScript = trim($scriptFile);
			if (!empty($destScript) && !in_array($destScript, $this->headPreMobileScriptFiles)) $this->headPreMobileScriptFiles[] = $destScript;
		}
	}
	/**
	 * HTMLヘッダに出力するRSSファイルを追加
	 *
	 * @param array	$rssFile	タイトル(title)、配信用URL(href)の連想配列。複数の場合は連想配列の配列。
	 * @return 					なし
	 */
	function addHeadRssFile($rssFile)
	{
		// パラメータエラーチェック
		if (!is_array($rssFile)) return;
		
		$line = $rssFile[0];
		if (is_array($line)){	// 複数追加の場合
			for ($i = 0; $i < count($line); $i++){
				// すでに追加済みかどうかチェック
				$url = trim($line[$i]['href']);
				if (!empty($url)){
					for ($j = 0; $j < count($this->headRssFiles); $j++){
						$storedUrl = $this->headRssFiles[$j]['href'];
						if ($url == $storedUrl) break;
					}
					if ($j == count($this->headRssFiles)){		// 見つからないときは追加
						$this->headRssFiles[] = array(	'href' => $url,		// リンク先URL
														'title' => $line[$i]['title']);		// タイトル
					}
				}
			}
		} else {		// 単数追加のとき
			// すでに追加済みかどうかチェック
			$url = trim($rssFile['href']);
			if (!empty($url)){
				for ($i = 0; $i < count($this->headRssFiles); $i++){
					$storedUrl = $this->headRssFiles[$i]['href'];
					if ($url == $storedUrl) break;
				}
				if ($i == count($this->headRssFiles)){		// 見つからないときは追加
					$this->headRssFiles[] = array(	'href' => $url,		// リンク先URL
													'title' => $rssFile['title']);		// タイトル
				}
			}
		}
	}
	/**
	 * RSSチャンネル部に出力するデータを設定
	 *
	 * @param array $rssData	RSSチャンネル部データ
	 * @return 					なし
	 */
	function setRssChannel($rssData)
	{
		if (!empty($rssData)) $this->rssChannel = $rssData;				// RSSチャンネルデータ
	}
	
	/**
	 * 表示ポジションを表示するかどうか
	 *
	 * @param int $mode   0=ポジション表示しない(通常画面)、1=ポジション表示、2=ウィジェット込みポジション表示
	 */
	function showPosition($mode)
	{
		$this->showPositionMode = $mode;
	}
	/**
	 * ウィジェットの単体表示を設定
	 */
	function showWidget()
	{
		$this->showWidget = true;
	}
	/**
	 * システム制御遷移モードを設定
	 *
	 * @param int $mode   0=設定なし、1=ログイン画面、10=サイト非公開、11=アクセス不可
	 */
	function setSystemHandleMode($mode)
	{
		$this->systemHandleMode = $mode;
	}
	/**
	 * システム制御遷移モード取得
	 */
	function getSystemHandleMode()
	{
		return $this->systemHandleMode;
	}
	/**
	 * 一般画面編集モードを設定
	 *
	 * @return 				なし
	 */
	function setEditMode()
	{
		$this->isEditMode = true;
	}
	/**
	 * 出力フォーマットがHTMLであるかを設定
	 *
	 * @param bool $isHtml	HTMLフォーマットかどうか
	 * @return 				なし
	 */
	function setOutputByHtml($isHtml)
	{
		$this->outputByHtml = $isHtml;
	}
	/**
	 * ヘルプ機能の使用可否を設定
	 *
	 * @param bool $status	ヘルプ機能を使用するかどうか
	 * @return 				なし
	 */
	function setUseHelp($status)
	{
		$this->useHelp = $status;
	}
	/**
	 * ヘルプ機能の使用可否を取得
	 *
	 * @return bool ヘルプ機能を使用するかどうか
	 */
	function getUseHelp()
	{
		return $this->useHelp;
	}
	/**
	 * JavaScriptのブラウザキャッシュの使用可否を設定
	 *
	 * @param bool $status	ブラウザキャッシュを使用するかどうか
	 * @return 				なし
	 */
	function setHasScriptCache($status)
	{
		$this->hasScriptCache = $status;
	}
	/**
	 * ページ作成処理を中断するかどうかを取得
	 *
	 * @return bool		true=中断、false=継続
	 */
	function isPageAbort()
	{
		return $this->isAbort;
	}
	/**
	 * 親ウィンドウを再描画
	 *
	 * @param int $defSerial	ページ定義シリアル番号
	 * @return 					なし
	 */
	function updateParentWindow($defSerial = 0)
	{
		$this->updateParentWindow = true;
		$this->updateDefSerial = $defSerial;			// 更新する項目のページ定義シリアル番号
	}
	/**
	 * CSSファイルの追加
	 *
	 * @param string $path	追加するファイルのパス(「ルート/scripts」ディレクトリからの相対パスで指定する)
	 * @return 				なし
	 */
	function addCssFile($path)
	{
		$destPath = trim($path, '/');
		if (!in_array($destPath, $this->defaultCssFiles)) $this->defaultCssFiles[] = $destPath;
	}
	/**
	 * CSSファイルの追加
	 *
	 * @param string $path	追加するファイルのパス(「ルート/scripts」ディレクトリからの相対パスで指定する)
	 * @return 				なし
	 */
	function addAdminCssFile($path)
	{
		$destPath = trim($path, '/');
		if (!in_array($destPath, $this->defaultAdminCssFiles)) $this->defaultAdminCssFiles[] = $destPath;
	}
	/**
	 * JavaScriptファイルの追加
	 *
	 * @param string $path	追加するファイルのパス(「ルート/scripts」ディレクトリからの相対パスで指定する)
	 * @return 				なし
	 */
	function addScriptFile($path)
	{
		$destPath = trim($path, '/');
		if (!empty($destPath) && !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;
	}
	/**
	 * 追加設定するテンプレートIDを返す
	 *
	 * @return string						テンプレートID
	 */
	function getOptionTemplateId()
	{
		global $gEnvManager;
		
		$optionTemplateId = '';
		
		// ページ情報取得
		$pageId = $gEnvManager->getCurrentPageId();

		if ($this->contentType == M3_VIEW_TYPE_BLOG){		// ページがブログタイプのとき
			if ($pageId == $this->gEnv->getDefaultPageId()){		// PCサイトのとき
				// ブログライブラリオブジェクトからテンプレートを取得
				$blogLibObj = $this->gInstance->getObject(self::BLOG_OBJ_ID);
				if (isset($blogLibObj)) $optionTemplateId = $blogLibObj->getOptionTemplate();
			}
		}
		return $optionTemplateId;
	}
	/**
	 * 使用した非共通ウィジェットの数を取得
	 *
	 * @return int				ウィジェット数
	 */
	function getNonSharedWidgetCount()
	{
		return $this->nonSharedWidgetCount;
	}
	/**
	 * ページのコンテンツタイプを取得
	 *
	 * @return string			コンテンツタイプ
	 */
	function getContentType()
	{
		return $this->contentType;
	}
	/**
	 * ページ作成開始
	 *
	 * HTTPヘッダを設定する。セッションを取得する。サブページIDを設定する。
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @return 								なし
	 */
	function startPage($request)
	{
		global $gEnvManager;
		global $gRequestManager;
		global $gInstanceManager;
		global $gAccessManager;
		global $gSystemManager;
		global $gDispManager;
		
		// 実行コマンドを取得
		$cmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		$task = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_TASK);
		$pageId = $gEnvManager->getCurrentPageId();
		$openBy = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPEN_BY);		// ウィンドウオープンタイプ

		// 管理者キーがあればGETまたはPOST値のセッションIDを使用する
		if ($gEnvManager->isAdminDirAccess()){
			if ($gAccessManager->isValidAdminKey()) session_id($gRequestManager->trimValueOf(session_name()));
		}
		
		// セッション変数を取得可能にする
		session_start();

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

		// セッションからユーザ情報を取得
		$userInfo = $gRequestManager->getSessionValueWithSerialize(M3_SESSION_USER_INFO);
		$gInstanceManager->setUserInfo($userInfo);
		
		// デバッグモードの表示
		if (M3_SYSTEM_DEBUG) echo 'Debug mode<br />';
		
		// ##### サブページIDの設定 #####
		if ($gEnvManager->isAdminDirAccess() &&		// 管理画面へのアクセスのとき
			($cmd == M3_REQUEST_CMD_LOGIN || $cmd == M3_REQUEST_CMD_LOGOUT)){				// ログイン、ログアウト場合は管理画面のページサブIDを指定
			$subId = $gEnvManager->getAdminDefaultPageSubId();		// 管理画面用のデフォルトページサブID
		} else {				
			$subId = $request->trimValueOf(M3_REQUEST_PARAM_PAGE_SUB_ID);// ページサブIDを取得
			if (empty($subId)){			// サブページIDが設定されていないとき
				// URLパラメータからコンテンツ形式を取得し、ページを選択
				$params = $gRequestManager->getQueryArray();
				$paramCount = count($params);

				// コマンド以外のパラメータ数が1つだけのときはパラメータからページ属性を判断する
				// 値が空でもキーがあれば属性を持つとする
				if ($paramCount == 0 && $gEnvManager->isSystemAdmin()){	// 2011/8/25 仕様変更 パラメータなしのときはダッシュボード属性のページを取得(ダッシュボードが使えるのはシステム管理者のみ)
					$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_DASHBOARD, $gEnvManager->getCurrentPageId());// ページサブIDを取得
					
					// ##### ダッシュボードはページの位置を示すので、ページのコンテンツ属性としない #####
					//$this->contentType = M3_VIEW_TYPE_DASHBOARD;		// ページのコンテンツタイプ
				//if ($paramCount == 1 || !empty($params[M3_REQUEST_PARAM_OPERATION_COMMAND])){
				} else if ($paramCount > 0 || !empty($params[M3_REQUEST_PARAM_OPERATION_COMMAND])){		// コマンド(プレビュー等)のとき、または複数パラメータでも可(2011/9/20)
					if (isset($params[M3_REQUEST_PARAM_CONTENT_ID]) || isset($params[M3_REQUEST_PARAM_CONTENT_ID_SHORT])){		// コンテンツIDのとき
						// ローカルメニューのURLからページを特定。ページが特定できないときはページ属性で取得。
						$url = $gEnvManager->getMacroPath($gEnvManager->getCurrentRequestUri());
						$ret = $this->db->getSubPageIdByMenuItemUrl($url, $gEnvManager->getCurrentPageId(), $rows);
						if ($ret){
							$rowCount = count($rows);
							for ($i = 0; $i < $rowCount; $i++){
								// コンテンツを表示するウィジェットがあるときはページサブIDを確定
								$widgetId = $this->db->getWidgetIdByType($gEnvManager->getCurrentPageId(), $rows[$i]['pd_sub_id'], M3_VIEW_TYPE_CONTENT);
								if (!empty($widgetId)){
									$subId = $rows[$i]['pd_sub_id'];
									break;
								}
							}
						}
						if (empty($subId)) $subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_CONTENT, $gEnvManager->getCurrentPageId());// ページサブIDを取得
						$this->contentType = M3_VIEW_TYPE_CONTENT;		// ページのコンテンツタイプ
					} else if (isset($params[M3_REQUEST_PARAM_PRODUCT_ID]) || isset($params[M3_REQUEST_PARAM_PRODUCT_ID_SHORT])){	// 製品IDのとき
						$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_PRODUCT, $gEnvManager->getCurrentPageId());// ページサブIDを取得
						$this->contentType = M3_VIEW_TYPE_PRODUCT;		// ページのコンテンツタイプ
					} else if (isset($params[M3_REQUEST_PARAM_BBS_ID]) || isset($params[M3_REQUEST_PARAM_BBS_ID_SHORT])){	// 掲示板投稿記事のとき
						$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_BBS, $gEnvManager->getCurrentPageId());// ページサブIDを取得
						$this->contentType = M3_VIEW_TYPE_BBS;		// ページのコンテンツタイプ
					} else if (isset($params[M3_REQUEST_PARAM_EVENT_ID]) || isset($params[M3_REQUEST_PARAM_EVENT_ID_SHORT])){	// イベント記事のとき
						$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_EVENT, $gEnvManager->getCurrentPageId());// ページサブIDを取得
						$this->contentType = M3_VIEW_TYPE_EVENT;		// ページのコンテンツタイプ
					} else if (isset($params[M3_REQUEST_PARAM_PHOTO_ID]) || isset($params[M3_REQUEST_PARAM_PHOTO_ID_SHORT])){	// フォトギャラリー写真のとき
						$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_PHOTO, $gEnvManager->getCurrentPageId());// ページサブIDを取得
						$this->contentType = M3_VIEW_TYPE_PHOTO;		// ページのコンテンツタイプ
					} else if ((isset($params[M3_REQUEST_PARAM_BLOG_ID]) || isset($params[M3_REQUEST_PARAM_BLOG_ID_SHORT])) ||				// ブログIDのとき
								(isset($params[M3_REQUEST_PARAM_BLOG_ENTRY_ID]) || isset($params[M3_REQUEST_PARAM_BLOG_ENTRY_ID_SHORT]))){	// ブログ記事のとき
						$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_BLOG, $gEnvManager->getCurrentPageId());// ページサブIDを取得
						$this->contentType = M3_VIEW_TYPE_BLOG;		// ページのコンテンツタイプ
					} else if (isset($params[M3_REQUEST_PARAM_ROOM_ID]) || isset($params[M3_REQUEST_PARAM_ROOM_ID_SHORT])){	// ユーザ作成コンテンツのとき
						$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_USER, $gEnvManager->getCurrentPageId());// ページサブIDを取得
						$this->contentType = M3_VIEW_TYPE_USER;		// ページのコンテンツタイプ
						
						// コンテンツを表示するウィジェットを取得
						$widgetId = $this->db->getWidgetIdByType($gEnvManager->getCurrentPageId(), $subId, M3_VIEW_TYPE_USER);
						if (!empty($widgetId)){
							// ルーム用の定義ID(所属グループID)を取得
							$roomId = isset($params[M3_REQUEST_PARAM_ROOM_ID]) ? $params[M3_REQUEST_PARAM_ROOM_ID] : $params[M3_REQUEST_PARAM_ROOM_ID_SHORT];
							$configId = $this->db->getWidgetConfigIdForRoom($roomId);

							// グループIDを定義IDとするページのページサブIDを取得
							$subPageId = $this->getPageSubIdByWidget($gEnvManager->getCurrentPageId(), $widgetId, $configId);
							if (!empty($subPageId)) $subId = $subPageId;
						}
					}
				}

				if (empty($subId)){
					// 「http://www.example.com?ページ名」「wcmd」の場合はwikiコンテンツページを選択
					$wikiCmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_WIKI_COMMAND);
					$pageName = $gRequestManager->getWikiPageFromQuery();		// 「=」なしのパラメータはwikiパラメータとする
			
					if (!empty($wikiCmd) || !empty($pageName)){			// Wikiコンテンツページを指定のとき
						// ページサブIDを取得
						$subId = $this->db->getSubPageIdWithContent(M3_VIEW_TYPE_WIKI, $gEnvManager->getCurrentPageId());
						$this->contentType = M3_VIEW_TYPE_WIKI;		// ページのコンテンツタイプ
					}
				}
				if (empty($subId)) $subId = $gEnvManager->getDefaultPageSubId();
			}
		}
		$gEnvManager->setCurrentPageSubId($subId);// サブページIDを設定

		// SSL通信機能がオンの場合は、アクセスされたURLのSSLをチェックし不正の場合は正しいURLにリダイレクト
		// 設定に間違いがある場合、管理画面にアクセスできなくなるので、一般画面のみ制御
		if ($gEnvManager->getUseSsl() || $gEnvManager->getUseSslAdmin()){
			if (!$gEnvManager->isAdminDirAccess()){		// 管理画面以外へのアクセスのとき
				$isSsl = $gEnvManager->isSslByCurrentPage();
				$currentUrl = $gEnvManager->getCurrentRequestUri();
				if ($isSsl){
					$correctUrl = str_replace('http://', 'https://', $currentUrl);
				} else {
					$correctUrl = str_replace('https://', 'http://', $currentUrl);
				}
				if ($currentUrl != $correctUrl) $this->redirect($correctUrl);
			}
		}
		
		// 画面設定取得
		$gDispManager->load();
			
		// ##### 画面に必要なスクリプトを追加 #####
		// スマートフォン用URLのときはスマートフォン用のjQueryを使用
		if ($gEnvManager->getIsSmartphoneSite()){
			$this->selectedJQueryFilename = ScriptLibInfo::getJQueryFilename(10);			// スマートフォン用jQueryファイル
			
			if (isset($this->libFiles[ScriptLibInfo::LIB_JQUERYS_MOBILE]['script'])){
				$scriptFiles = $this->libFiles[ScriptLibInfo::LIB_JQUERYS_MOBILE]['script'];
				if (count($scriptFiles) > 0) $this->selectedJQueryMobileFilename = $scriptFiles[0];		// 使用対象のjQueryMobileファイル
			}
		}
		
		// Magic3管理用のスクリプトを追加
		if (!$gEnvManager->getIsMobileSite()){		// 携帯用URL以外のとき
			if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
				//if ($gEnvManager->isSystemAdmin()){		// 管理者権限がある場合のみ有効
				if ($gEnvManager->isSystemManageUser()){		// システム運用権限がある場合のみ有効
					$this->isEditMode = true;			// 一般画面編集モード
					
					// ライブラリを追加
					if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET){	// ウィジェット詳細設定画面のとき
						$this->addAdminScript('', ScriptLibInfo::LIB_FCKEDITOR);// FCKEditorスクリプト追加
					} else if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// 管理画面(ウィジェット付きポジション表示)のとき
						//$this->addAdminScript('', ScriptLibInfo::LIB_JQUERY_JQEASYPANEL);		// パネルメニュー(一般画面と管理画面の切り替え等)用
					}
					$this->addAdminScript('', ScriptLibInfo::LIB_JQUERY_CLUETIP);// HELP用スクリプト追加
				
					// スクリプトが必要なウィジェットをすべて取得
					$this->db->getWidgetsIdWithLib($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId(), $rows);
					for ($i = 0; $i < count($rows); $i++){
						$this->addAdminScript($task, trim($rows[$i]['wd_add_script_lib']));
					}
					if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET){	// ウィジェット詳細設定画面のとき
						// ウィジェット情報取得
						$widgetId = $request->trimValueOf(M3_REQUEST_PARAM_WIDGET_ID);
						$ret = $this->db->getWidgetInfo($widgetId, $row);
						if ($ret) $this->addAdminScript($task, trim($row['wd_add_script_lib_a']));		// 管理機能用スクリプト
					}
				}
			} else {		// 一般画面へのアクセスのとき
				if ($cmd != M3_REQUEST_CMD_DO_WIDGET &&							// ウィジェット単体実行でない
					$cmd != M3_REQUEST_CMD_RSS){								// RSS配信でない
					if ($gEnvManager->isSystemManageUser()){
						$this->isEditMode = true;			// 一般画面編集モード
						$this->isPageEditable = true;		// 一般画面ページ編集可能モードに設定
					
						// システム運用権限がある場合は管理用スクリプトを追加
						// 一般画面と管理画面の切り替え用のスライドメニューバーには管理用スクリプト,CSSが必要
						$this->addScriptFile($this->selectedJQueryFilename);		// JQueryスクリプト追加
						$this->addScriptFile(self::M3_ADMIN_SCRIPT_FILENAME);		// 管理スクリプトライブラリ追加
						//$this->addScript('', ScriptLibInfo::LIB_JQUERY_JQEASYPANEL);		// パネルメニュー(一般画面と管理画面の切り替え等)用
						$this->addScript('', ScriptLibInfo::LIB_JQUERY_CLUETIP);// HELP用スクリプト追加
						
						$this->addCssFile(self::M3_ADMIN_CSS_FILE);		// 管理機能用CSS
					}
				}
			}
		}
		// 現在の言語でページ情報を取得
		$ret = $this->db->getPageInfo($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId(), $gEnvManager->getCurrentLanguage(), $row);

		// デフォルトのページ情報を取得
		$line = $this->getPageInfo($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId());
		if (!empty($line)){
			// ショートURLで取得できない場合は、ページコンテンツタイプを取得
			if (empty($this->contentType)) $this->contentType = $line['pn_content_type'];
		}

		// 現在の言語でヘッダを設定
		if (empty($row)) $row = $line;
		if (!empty($row)){
			// 現在のページ情報を設定
			$this->currentPageInfo = $row;			// 現在のページのページ情報
			
			$title = $row['pn_meta_title'];		// 画面タイトル
			$desc = $row['pn_meta_description'];		// ページ要約
			$keyword = $row['pn_meta_keywords'];		// ページキーワード
			
			if (!empty($title)) $this->setHeadSubTitle($title);
			if (!empty($desc)) $this->setHeadDescription($desc);
			if (!empty($keyword)) $this->setHeadKeywords($keyword);
		}
		
		// 画面透過モードを設定
		if ($openBy == 'tabs') $this->isTransparentMode = true;		// 画面透過モード
	}
	/**
	 * スクリプト追加情報から、管理機能用のJavascriptファイル、CSSを追加する
	 *
	 * @param string $task				指定タスク
	 * @param string $scriptInfo		スクリプト追加情報
	 * @return 							なし
	 */
	function addAdminScript($task, $scriptInfo)
	{
		$itemArray = explode(self::SCRIPT_LIB_SEPARATOR, strtolower(trim($scriptInfo)));// 小文字に変換したものを解析
		for ($i = 0; $i < count($itemArray); $i++){
			$pos = strpos($itemArray[$i], '=');
			if ($pos === false){// 見つからないときは、タスクが指定されないとき
				$libs = trim($itemArray[$i]);
			} else {		// タスク指定のとき
				list($libTask, $libs) = explode('=', trim($itemArray[$i]));
				$libTask = trim($libTask);
				$libs = trim($libs);
				if (empty($libTask) || $libTask != $task) $libs = '';			// タスクが異なるときは追加しない
			}
			if (!empty($libs)){		// // スクリプト、CSSの追加を行うとき
				$libsArray = explode(',', $libs);
				for ($j = 0; $j < count($libsArray); $j++){
					$lib = strtolower(trim($libsArray[$j]));// 小文字に変換
					if (isset($this->libFiles[$lib])){		// ライブラリが存在するとき
						if (isset($this->libFiles[$lib]['script'])){
							$scriptFiles = $this->libFiles[$lib]['script'];
							for ($l = 0; $l < count($scriptFiles); $l++){
								$this->addAdminScriptFile($scriptFiles[$l]);		// 管理機能用のスクリプト追加
							}
						}
						if (isset($this->libFiles[$lib]['css'])){
							$cssFiles = $this->libFiles[$lib]['css'];
							for ($l = 0; $l < count($cssFiles); $l++){
								$this->addAdminCssFile($cssFiles[$l]);		// 管理機能用のCSS追加
							}
						}
						if (strncmp($lib, 'jquery-ui.', 10) == 0){		// jQuery UIのwidgetsまたはeffectsのとき
							// jQueryUIテーマを追加
							$this->addHeadCssFile($this->getAdminDefaultTheme());		// CSS追加
						}
					}
				}
			}
		}
	}
	/**
	 * スクリプト追加情報から、通常機能用のJavascriptファイル、CSSを追加する
	 *
	 * @param string $task				指定タスク
	 * @param string $scriptInfo		スクリプト追加情報
	 * @return 							なし
	 */
	function addScript($task, $scriptInfo)
	{
		// ライブラリ情報取得
		$jQueryUiInfo = ScriptLibInfo::getJQueryUiInfo();
		
		$itemArray = explode(self::SCRIPT_LIB_SEPARATOR, strtolower(trim($scriptInfo)));// 小文字に変換したものを解析
		for ($i = 0; $i < count($itemArray); $i++){
			$pos = strpos($itemArray[$i], '=');
			if ($pos === false){// 見つからないときは、タスクが指定されないとき
				$libs = trim($itemArray[$i]);
			} else {		// タスク指定のとき
				list($libTask, $libs) = explode('=', trim($itemArray[$i]));
				$libTask = trim($libTask);
				$libs = trim($libs);
				if (empty($libTask) || $libTask != $task) $libs = '';			// タスクが異なるときは追加しない
			}
			if (!empty($libs)){		// // スクリプト、CSSの追加を行うとき
				$libsArray = explode(',', $libs);
				for ($j = 0; $j < count($libsArray); $j++){
					$lib = strtolower(trim($libsArray[$j]));// 小文字に変換
					
					// jQueryライブラリ等、デフォルトでは追加されないライブラリを追加
					if (strcmp($lib, 'jquery') == 0){// jQuery本体のとき
						$this->addScriptFile($this->selectedJQueryFilename);		// JQueryスクリプト追加
					} else if (isset($this->libFiles[$lib])){		// ライブラリが存在するとき
						// ライブラリの依存ライブラリファイルを追加
						if (strncmp($lib, 'jquery.', 7) == 0){		// jQueryプラグインのとき
							$this->addScriptFile($this->selectedJQueryFilename);		// JQueryスクリプト追加
							if (strcmp($lib, 'jquery.mobile') == 0){	// jQueryMobileファイルのとき
								// ##### jQueryMobileが読み込まれる前に読み込む必要があるスクリプトを設定 #####
								if (!empty($this->headPreMobileScriptFiles)){		// jQueryMobileファイルの前に出力
									for ($l = 0; $l < count($this->headPreMobileScriptFiles); $l++){
										$this->addScriptFile($this->headPreMobileScriptFiles[$l]);		// 通常機能用のスクリプト追加
									}
								}
							}
						} else if (strcmp($lib, ScriptLibInfo::LIB_JQUERY_UI) == 0){	// jQuery UI
							$this->addScriptFile($this->selectedJQueryFilename);		// JQueryスクリプト追加
						} else if (strcmp($lib, ScriptLibInfo::LIB_JQUERY_UI_PLUS) == 0){	// jQuery UI plus
							$this->addScriptFile($this->selectedJQueryFilename);		// JQueryスクリプト追加
							$this->addScriptFile($this->selectedJQueryUiFilename);		// jQuery Coreスクリプト追加
						} else if (strncmp($lib, 'jquery-ui.', 10) == 0){		// jQuery UIのwidgetsまたはeffectsのとき
							// 依存ライブラリ追加
							$parentLib = $jQueryUiInfo[$lib];		// 依存ライブラリ取得
							for ($l = 0; $l < count($parentLib); $l++){
								$addLib = $parentLib[$l];
								
								// ライブラリのファイルを追加
								if (isset($this->libFiles[$addLib]['script'])){
									$scriptFiles = $this->libFiles[$addLib]['script'];
									for ($m = 0; $m < count($scriptFiles); $m++){
										$this->addScriptFile($scriptFiles[$m]);		// 通常機能用のスクリプト追加
									}
								}
								if (isset($this->libFiles[$addLib]['css'])){
									$cssFiles = $this->libFiles[$addLib]['css'];
									for ($m = 0; $m < count($cssFiles); $m++){
										$this->addCssFile($cssFiles[$m]);		// 通常機能用のCSS追加
									}
								}
							}
							// jQueryUIテーマを追加
							$this->addHeadCssFile($this->getAdminDefaultTheme());		// CSS追加
						}
						
						// ライブラリ自体のファイルを追加
						if (isset($this->libFiles[$lib]['script'])){
							$scriptFiles = $this->libFiles[$lib]['script'];
							for ($l = 0; $l < count($scriptFiles); $l++){
								$this->addScriptFile($scriptFiles[$l]);		// 通常機能用のスクリプト追加
							}
						}
						if (isset($this->libFiles[$lib]['css'])){
							$cssFiles = $this->libFiles[$lib]['css'];
							for ($l = 0; $l < count($cssFiles); $l++){
								$this->addCssFile($cssFiles[$l]);		// 通常機能用のCSS追加
							}
						}
					}
				}
			}
		}
	}
	/**
	 * ページ作成終了
	 *
	 * ・最終HTML出力
	 * ・セッション情報の保存
	 * ・ウィジェットで生成されたHTTPヘッダを設定する
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @param bool $getOutput				出力を取得するかどうか
	 * @return string        				最終出力HTML
	 */
	function endPage($request, $getOutput = false)
	{
		global $gRequestManager;
		global $gInstanceManager;
		global $gEnvManager;
		global $gDispManager;
		
		// ページ作成処理を中断するかどうか
		if ($this->isAbort) return '';
		
		$contents = '';
		
		// 実行コマンドを取得
		$cmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		
		// 最終HTML(ページ全体で使用するHTML)の出力
		if ($cmd != M3_REQUEST_CMD_DO_WIDGET){		// ウィジェット単体オペレーションのときは出力しない
			if ($getOutput){
				$contents = $this->getLastContents($request);
			} else {
				echo $this->getLastContents($request);
			}
		}
		
		// セッションへユーザ情報を保存
		$userInfo = $gInstanceManager->getUserInfo();
		$gRequestManager->setSessionValueWithSerialize(M3_SESSION_USER_INFO, $userInfo);
		
		// 画面設定保存
		$gDispManager->save();
			
		// キャッシュリミッタは、各リクエスト毎に(アウトプットバッファー が無効な場合は、
		// session_start()がコールされる 前に) session_cache_limiter()をコールする必要がある。
	 	// キャッシュを残す設定
//	 	session_cache_limiter('private');
//	 	session_cache_expire(5);
		if ($this->isRedirect) return '';			// リダイレクトの場合は終了

		// ########## HTTPヘッダ出力処理 ########
		if (headers_sent($filename, $linenum)){		// HTTPヘッダが既に送信されているとき
			echo "$filename の $linenum 行目でヘッダがすでに送信されています。";
		} else {
			if ($gEnvManager->isMobile()){		// 携帯の場合
				// ドコモ端末の場合はリクエストヘッダにXHTMLを指定しないとXHTMLを処理しない
				$agent = $gInstanceManager->getMobileAgent();
				if ($agent->isDoCoMo()){	// ドコモ端末のとき
					header('Content-Type: application/xhtml+xml;');
				}
			} else {
				// キャッシュを無効にする場合
				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ヘッダに格納
				$gInstanceManager->getAjaxManager()->header();
			}
			// システム制御画面が設定されている場合はステータスコードを変更
			//if ($this->gEnv->getIsMaintenance()){
			if (!$this->isRedirect){			// リダイレクトがセットされていない場合
				switch ($this->systemHandleMode){
					case 10:			// サイト非公開(システムメンテナンス)
						header('HTTP/1.1 503 Service Temporarily Unavailable');
						header('Status: 503 Service Temporarily Unavailable');
						break;
					case 11:			// アクセス禁止のとき
						header('HTTP/1.1 403 Forbidden');
						header('Status: 403 Forbidden');
						break;
				}
			}
		}
		return $contents;
	}
	/**
	 * ページ作成処理中断
	 *
	 * @return 							なし
	 */
	function abortPage()
	{
		global $gInstanceManager;
		global $gRequestManager;
		
		// HTTPヘッダを削除(PHP 5.3以上で有効)
		if (version_compare(PHP_VERSION, '5.3.0') >= 0) header_remove();

		// exit()等でabortPage()が最後の処理になってしまう可能性があるのでなるべく必要な処理を行う
		//if (ob_get_level() > 0) ob_end_clean();// バッファ内容が残っているときは破棄
		while (ob_get_level()) ob_end_clean();	// バッファ削除方法変更(2009/12/2)
		
		// セッションへユーザ情報を保存
		$userInfo = $gInstanceManager->getUserInfo();
		$gRequestManager->setSessionValueWithSerialize(M3_SESSION_USER_INFO, $userInfo);
		
		$this->isAbort = true;					// ページ作成処理を中断するかどうか
	}
	/**
	 * 強制終了を実行
	 *
	 * @return 		なし
	 */
	function exitSystem()
	{
		global $gEnvManager;
		global $gAccessManager;
		
		// DBが使用可能であれば、アクセスログのユーザを登録
		if ($gEnvManager->canUseDb()) $gAccessManager->accessLogUser();
		
		exit;		// システム終了
	}
	/**
	 * Joomla!v1.5タグを読み込んでウィジェット実行
	 *
	 * @param string         $srcBuf		バッファデータ
	 * @return string						変換後文字列
	 */
	function launchWidgetByJoomlaTag($srcBuf)
	{
		$replace = array();
		$matches = array();
		$destBuf = $srcBuf;
		
		if (preg_match_all('#<jdoc:include\ type="([^"]+)" (.*)\/>#iU', $srcBuf, $matches)){
			$count = count($matches[1]);
			for($i = 0; $i < $count; $i++)
			{
				$contents = '';
				$type  = $matches[1][$i];
				$attr = array();
				if (strcasecmp($type, 'head') == 0){		// ヘッダ埋め込みタグの場合
					ob_clean();
					$this->getHeader();
					$contents = ob_get_contents();
				} else if (strcasecmp($type, 'modules') == 0 || 
							strcasecmp($type, 'module') == 0){		// ポジションタグの場合
					$name = '';			// ポジション名
					$style = '';		// 表示スタイル
					$params = explode(' ', $matches[2][$i]);
					for ($j = 0; $j < count($params); $j++){
						list($key, $value) = explode('=', $params[$j]);
						if (strcasecmp($key, 'name') == 0){
							$name = strtolower(trim($value, "\"'"));
							$attr['name'] = $name;
						} else if (strcasecmp($key, 'style') == 0){
							// スタイルは大文字小文字の区別あり
							$style = trim($value, "\"'");
						} else if (strcasecmp($key, 'artstyle') == 0){		// 表示スタイル
							$attr['artstyle'] = trim($value, "\"'");
						}
					}
					if (!empty($name)){		// ポジション名が取得できたとき
						// Joomla!では、テンプレートの「jdoc:include」タグの属性styleが空のときは「none」で処理される
						// Joomla!デフォルトで設定可能なのは「none,table,horz,xhtml,rounded,outline」
						if (empty($style)){
							if (strStartsWith($name, 'user')){// ナビゲーションメニュー位置の場合
								$style = '_mainmenu';		// デフォルトはナビゲーション型
							} else {
								$style = 'none';
							}
						}
						// ウィジェットの出力を取得
						$contents = $this->getContents($name, $style, false, $attr);
					}
				} else if (strcasecmp($type, 'component') == 0){	// メインポジションタグの場合
					$contents = $this->getContents('main', 'xhtml', false, $attr);
				} else if (strcasecmp($type, 'message') == 0){	// メッセージタグの場合
				}
				$replace[$i] = $contents;
			}
			ob_clean();
			$destBuf = str_replace($matches[0], $replace, $srcBuf);
		}
		return $destBuf;
	}
	/**
	 * 遅延ウィジェット実行
	 *
	 * 遅延実行インデックスのついているウィジェットをインデックス順に実行し、出力バッファデータ内のタグの位置に出力を埋め込む
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @param string         $srcBuf		バッファデータ
	 * @return string						変換後文字列
	 */
	function lateLaunchWidget($request, $srcBuf)
	{
		global $gEnvManager;
		global $gErrorManager;
		global $gDesignManager;
		
		// ウィジェットヘッダ(Joomla!1.0用)を出力のタイプを取得
		$widgetHeaderType = $this->getTemplateWidgetHeaderType();
					
		// 遅延実行ウィジェットをインデックス順にソート
		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, $style, $cssStyle, $title, $shared) = $this->latelaunchWidgetParam[$i];
				if ($wId == $widgetId){
					// パラメータ初期化
					$this->lastHeadCss = '';			// 最後に設定したHTMLヘッダにCSS出力する文字列
					$this->lastHeadScript = '';			// 最後に設定したHTMLヘッダにJavascript出力する文字列
					$this->lastHeadString = '';			// 最後に設定したHTMLヘッダに出力する任意文字列
					
					// バッファ作成
					ob_start();

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

					// その他パラメータ取得
					$configId = $confId;		// ウィジェット定義ID
					if ($configId == 0) $configId = '';
					$prefix = $preId;		// サフィックス文字列
			
					// Joomla!1.0テンプレートのときはウィジェットタイトルを出力
					$joomlaTitleVisble = false;
					if ($widgetHeaderType > 0 && empty($style)){			// Joomla!1.0テンプレートのとき
						if (!empty($title)){
							if ($widgetHeaderType == 1){		// PC用ウィジェットヘッダ出力
								echo '<table ' . self::JOOMLA10_DEFAULT_WIDGET_MENU_PARAM . '>' . M3_NL;
								echo '<tr><th>' . $title . '</th></tr>' . M3_NL;
								echo '<tr><td>' . M3_NL;
								$joomlaTitleVisble = true;
							} else if ($widgetHeaderType == 2){			// 携帯用ウィジェットヘッダ出力
								echo '<div>' . $title . '</div>' . M3_NL;
								$joomlaTitleVisble = true;
							}
						}
					}
					// ウィジェットの外枠タグを設定
					//echo '<div class="' . self::WIDGET_TAG_HEAD_SHORT . $widgetId . '">' . M3_NL;
					// ウィジェット親のCSS定義があるときは、タグを追加
					if (!empty($cssStyle)) echo '<div style="' . $cssStyle . '">' . M3_NL;
					
					// ウィジェットの前出力
					echo $gDesignManager->getAdditionalWidgetOutput(true);
				
					// 作業中のウィジェットIDを設定
					$gEnvManager->setCurrentWidgetId($widgetId);

					// ウィジェット定義IDを設定
					$gEnvManager->setCurrentWidgetConfigId($configId);
					
					// ページ定義のシリアル番号を設定
					$gEnvManager->setCurrentPageDefSerial($serial);
		
					// パラメータを設定
					$gEnvManager->setCurrentWidgetPrefix($prefix);		// プレフィックス文字列
		
					// ウィジェットのタイトルを設定
					$gEnvManager->setCurrentWidgetTitle('');
				
					// ウィジェットのページ共通状況を設定
					$gEnvManager->setIsCurrentWidgetShared($shared);
				
					// 実行ログを残す
					$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('');				// プレフィックス文字列
					
					// ウィジェットのページ共通状況を解除
					$gEnvManager->setIsCurrentWidgetShared(false);
					
					// ウィジェットのタイトルを取得
					$newTitle = $gEnvManager->getCurrentWidgetTitle();

					// ウィジェットの後出力
					echo $gDesignManager->getAdditionalWidgetOutput(false);
				
					// ウィジェット親のCSS定義があるときは、タグを追加
					if (!empty($cssStyle)) echo '</div>' . M3_NL;
					// ウィジェットの外枠タグを設定
					//echo '</div>' . M3_NL;
					
					// Joomla!1.0テンプレートのときはタイトルを出力
					if ($joomlaTitleVisble && $widgetHeaderType == 1){		// PC用ウィジェットヘッダ出力
						echo '</td></tr>' . M3_NL;
						echo '</table>' . M3_NL;
					}
					
					// 現在のバッファ内容を取得し、バッファを破棄
					$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 (!empty($newTitle)) $title = $newTitle;
					$tag = self::WIDGET_ID_TITLE_TAG_START . $widgetId . self::WIDGET_ID_SEPARATOR . $index . self::WIDGET_ID_TITLE_TAG_END;
					$destBuf = str_replace($tag, $title, $destBuf);
				}
			}
		}
		$destBuf = $this->replaceHead($destBuf);
		return $destBuf;
	}
	/**
	 * ヘッダ部マクロ変換処理
	 *
	 * @param string         $srcBuf		変換元
	 * @return string						変換後文字列
	 */
	function replaceHead($srcBuf)
	{
		$destBuf = $srcBuf;
		
		// ##### ヘッダ部分の置換 #####
		if ($this->outputHead){				// HTMLヘッダ出力を行っているとき
			// タグ変換用文字列の取得
			$replaceStr = $this->getHeaderOutput();
			
			// HTMLヘッダのデータ埋め込み
			$destBuf = str_replace(self::HEAD_TAGS, $replaceStr, $destBuf);
		}
		$this->replaceHeadDone = true;			// ヘッダマクロ変換処理が完了したかどうか
		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);
		if ($gEnvManager->getIsMobileSite()){		// 携帯用アクセスポイントの場合
			$this->redirect('?' . M3_REQUEST_PARAM_PAGE_SUB_ID . '=' . $gEnvManager->getCurrentPageSubId() . '&' . $todo, true/*遷移時のダイアログ表示を抑止*/);
		} else {
			$this->redirect('?' . M3_REQUEST_PARAM_PAGE_SUB_ID . '=' . $gEnvManager->getCurrentPageSubId() . '&' . $todo);
		}
	}
	/**
	 * 最終HTML出力処理
	 *
	 * テンプレートの出力が完了した後、HTMLとして出力する最後の出力を行う
	 * 追加するHTMLは主にウィンドウ管理用のスクリプト
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @return string        				最終HTML
	 */
	function getLastContents($request)
	{
		global $gEnvManager;

		$contents = '';
		$initScript = '';		// 初期化用スクリプト
		$pageId		= $gEnvManager->getCurrentPageId();
		$pageSubId	= $gEnvManager->getCurrentPageSubId();
		$cmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		
		// RSS配信のときは終了
		if ($cmd == M3_REQUEST_CMD_RSS) return '';
		
		if ($gEnvManager->getIsMobileSite()){		// 携帯用URLのとき
		} else {			// PC用URLのとき
			if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
				//if ($gEnvManager->isSystemAdmin()){		// 管理者権限がある場合のみ有効
				if ($gEnvManager->isSystemManageUser()){		// システム運用権限がある場合のみ有効
					// ウィジェットレイアウト用カーソル
					if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
						//$contents .= '<div class="clear"></div>' . M3_NL;
						/*
						$contents .= '<div id="m3_overlay">' . M3_NL;		// ロード中表示
						$contents .= '<div id="preloader"><img src="' . $gEnvManager->getImagesUrl() . '/system/loader.gif" alt="" /></div>' . M3_NL;
						$contents .= '</div>' . M3_NL;*/

						// テンプレート上のポジション名
						if (count($this->viewPosId) > 0){
							$posArrayStr = '[';
							for ($i = 0; $i < count($this->viewPosId); $i++){
								$posArrayStr .= '\'#' . $this->viewPosId[$i] . '\'';
								//$posArrayStr .= '\'' . $this->viewPosId[$i] . '\'';
								if ($i < count($this->viewPosId) - 1) $posArrayStr .= ',';
							}
							$posArrayStr .= ']';
							$contents .= 'var M3_POSITIONS=' . $posArrayStr . ';' . M3_NL;
						}
						// 画面定義のリビジョン番号
						$contents .= 'var M3_REVISION=' . $this->pageDefRev . ';' . M3_NL;
				
						// 更新用関数追加
						$contents .= 'function m3UpdateByConfig(serial){' . M3_NL;
						$contents .= M3_INDENT_SPACE . 'window.m3.m3UpdateByConfig(serial);' . M3_NL;
						$contents .= '}' . M3_NL;
					
						// 携帯用テンプレートのときは、プレビューウィンドウの更新を通知する
						/*if ($gEnvManager->getCurrentTemplateType() == 1){
							$contents .= 'if (window.parent.m3UpdateByChildWindow) window.parent.m3UpdateByChildWindow();' . M3_NL;
						}*/
					} else if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET){			// ウィジェット設定画面
						// 画面更新用関数追加
						$contents .= 'function m3UpdateByConfig(serial){' . M3_NL;
						$contents .= M3_INDENT_SPACE . 'var href = window.location.href.split("#");' . M3_NL;
						$contents .= M3_INDENT_SPACE . 'window.location.href = href[0];' . M3_NL;
						$contents .= M3_INDENT_SPACE . 'm3UpdateParentWindow();' . M3_NL;		// 親ウィンドウ更新
						$contents .= '}' . M3_NL;
					}
					// 管理画面からの親画面の更新
//					if ($this->updateParentWindow){			// 親ウィンドウ再描画のとき
//						$initScript .= M3_INDENT_SPACE . 'm3UpdateParentWindowByConfig(' . $this->updateDefSerial . ');' . M3_NL;// 更新する項目のページ定義シリアル番号
//					}
					
					// ##### ヘルプシステムの組み込み #####
					// ヘルプシステムはすべての初期処理完了後に実行する
					// ヘルプシステムは、「span」タグで埋め込み、「title」属性を使用する
					if ($this->useHelp){			// ヘルプ表示のとき
						$initScript .= M3_INDENT_SPACE . '$(\'span.m3help\').cluetip({splitTitle: \'|\'});' . M3_NL;
					} else {			// ヘルプ非表示のときは、title属性をクリアする
						$initScript .= M3_INDENT_SPACE . '$(\'span.m3help\').attr(\'title\', \'\');' . M3_NL;
					}
				}
			} else {		// 通常画面のとき
				if ($gEnvManager->isSystemManageUser()){		// システム運用権限がある場合のみ有効
					// 画面更新用関数追加
					$contents .= 'function m3UpdateByConfig(serial){' . M3_NL;
					$contents .= M3_INDENT_SPACE . 'var href = window.location.href.split("#");' . M3_NL;
					$contents .= M3_INDENT_SPACE . 'window.location.href = href[0];' . M3_NL;
					$contents .= '}' . M3_NL;
				}
			}
		}
		$destContents = '';
		if (!empty($contents) || !empty($initScript)){
			$destContents .= '<script type="text/javascript">' . M3_NL;
			$destContents .= '//<![CDATA[' . M3_NL;
			$destContents .= $contents;
			if (!empty($initScript)){		// 初期化用スクリプト
				$destContents .= '$(function(){' . M3_NL;
				$destContents .= $initScript;
				$destContents .= '});' . M3_NL;
			}
			$destContents .= '//]]>' . M3_NL;
			$destContents .= '</script>' . M3_NL;
		}
		return $destContents;
	}
	/**
	 * オプションHTML出力処理
	 *
	 * テンプレートの出力が完了した後、HTMLとして出力する最後の出力を行う
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @return string        				最終HTML
	 */
	function getOptionContents($request)
	{
		global $gEnvManager;
		
		$contents = '';
		
		// Magic3出力コメント
		if (!$gEnvManager->isMobile() && $this->outputByHtml){		// 携帯以外で、HTML出力のとき
			$contents .= '<!-- created by ' . M3_SYSTEM_NAME . ' v' . M3_SYSTEM_VERSION . ' - http://www.magic3.org -->' . M3_NL;
			$contents .= '<!-- convert time: ' . sprintf('%01.03f', microtime(true) - M3_MTIME) . ' -->' . M3_NL;
		}
		return $contents;
	}
	/**
	 * Widget単体起動用のHTMLのヘッダ部(headタグ)出力
	 *
	 * Widgetの出力方法は、以下のパターンがある
	 *  ・HTMLヘッダ付加 - Widget単体で画面出力するためにHTMLヘッダを付加するパターン
	 *  ・HTMLヘッダなし - Wiget単体のタグ出力のみのパターン
	 *
	 * @param string $cmd		起動コマンド
	 */
	function startWidget($cmd)
	{
		global $gEnvManager;
		global $gRequestManager;
				
		// ウィジェット単体表示のときのみ出力
		if (!$this->showWidget) return;
		
		// パラメータ取得
		$openBy = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPEN_BY);		// ウィンドウオープンタイプ
		$task = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_TASK);

		// XHTML形式ではヘルプ機能にエラーが出るので一時的に戻す
		echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' . M3_NL;
		echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">' . M3_NL;
		echo '<head>' . M3_NL;

		// HTMLのヘッダ部(headタグ内)出力
		$this->getHeader();

		// 現在のウィジェットを取得
		$widgetId = $gEnvManager->getCurrentWidgetId();		// カレントのウィジェットID
		
		// URLを作成
		if ($gEnvManager->getUseSslAdmin()){
			$templatesUrl = $gEnvManager->getSslTemplatesUrl();	// テンプレート読み込み用パス
			$widgetsUrl = $gEnvManager->getSslWidgetsUrl();		// ウィジェット格納パス
		} else {
			$templatesUrl = $gEnvManager->getTemplatesUrl();	// テンプレート読み込み用パス
			$widgetsUrl = $gEnvManager->getWidgetsUrl();		// ウィジェット格納パス
		}
	
		// ##### テンプレートのCSSの読み込み #####
		if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET ||	// ウィジェット詳細設定画面のとき
			$cmd == M3_REQUEST_CMD_DO_WIDGET){		// ウィジェット単体実行のとき
			// 管理用テンプレート
			echo '<link href="' . $templatesUrl . '/_admin/css/style.css" rel="stylesheet" type="text/css" />' . M3_NL;
			echo '<!--[if IE]><link rel="stylesheet" type="text/css" media="screen" href="' . $templatesUrl . '/_admin/css/iestyles.css" /><![endif]-->' . M3_NL;
		} else if ($cmd == M3_REQUEST_CMD_SHOW_WIDGET){		// ウィジェットの単体表示のとき
			// ウィジェットが管理用ウィジェットかどうかチェック
			if ($widgetId == self::ADMIN_WIDGET_ID){			// 管理用ウィジェットの場合
				// 管理用テンプレート
				echo '<link href="' . $templatesUrl . '/_admin/css/style.css" rel="stylesheet" type="text/css" />' . M3_NL;
				echo '<!--[if IE]><link rel="stylesheet" type="text/css" media="screen" href="' . $templatesUrl . '/_admin/css/iestyles.css" /><![endif]-->' . M3_NL;
			} else {
				$curTemplate = $this->gSystem->defaultTemplateId();
				$templateFile = $templatesUrl . '/' . $curTemplate . self::DEFAULT_TEMPLATE_CSS_FILE;
				echo '<link href="' . $templateFile . '" rel="stylesheet" type="text/css" />' . M3_NL;
			}
		}
		// ウィジェット情報取得
		$ret = $this->db->getWidgetInfo($widgetId, $row);

		// ##### 共通ライブラリ読み込み設定 #####
		if ($cmd == M3_REQUEST_CMD_DO_WIDGET){		// ウィジェット単体実行のとき
			$scritLib = trim($row['wd_add_script_lib']);
			if (!empty($scritLib)) $this->addScript($task, $scritLib);
		}
				
		// CSS読み込みが指定されていて、ディレクトリがあるときはディレクトリ内読み込み
		if ($row['wd_read_css']){
			$searchPath = $gEnvManager->getWidgetsPath() . '/' . $widgetId . '/' . 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)
						&& strncmp($file, '_', 1) != 0){		// 「_」で始まる名前のファイルは読み込まない
						
						// CSSへのURLを作成
						$cssURL = $widgetsUrl . '/' . $widgetId . '/' . M3_DIR_NAME_CSS . '/' . $file;
						echo '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
					}
				}
				$dir->close();
			}
		}
		
		// スクリプト読み込みが指定されていて、ディレクトリがあるときはディレクトリ内読み込み
		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)
						&& strncmp($file, '_', 1) != 0){		// 「_」で始まる名前のファイルは読み込まない
						
						// スクリプトへのURLを作成
						$scriptURL = $widgetsUrl . '/' . $widgetId . '/' . M3_DIR_NAME_SCRIPTS . '/' . $file;
						
						// スクリプトをキャッシュ保存しない場合は、パラメータを付加
						if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
						echo '<script type="text/javascript" src="' . $scriptURL . '"></script>' . M3_NL;
					}
				}
				$dir->close();
			}
		}
		
		// ウィジェットのタイトルを設定
		$title = $row['wd_name'];
		if (empty($title)) $title = $row['wd_id'];
		echo '<title>' . $title . '</title>' . M3_NL;
		echo '</head>' . M3_NL;
		// タブでウィンドウを開く場合は背景を透過モードにする
		if ($this->isTransparentMode){
			echo '<body style="background-color:transparent;">' . M3_NL;
		} else {
			echo '<body>' . M3_NL;
		}
		
		// 別ウィンドウで表示のときは、「閉じる」ボタンを表示
		if ($cmd == M3_REQUEST_CMD_SHOW_WIDGET ||		// ウィジェットの単体表示のとき
			$cmd == M3_REQUEST_CMD_CONFIG_WIDGET ||	// ウィジェット詳細設定画面のとき
			$cmd == M3_REQUEST_CMD_DO_WIDGET){		// ウィジェット単体実行のとき
			if (!empty($openBy)){
				//echo '<br />' . M3_NL;
									
				// サーバ指定されている場合はサーバ情報を取得
				$serverName = '';
				$server = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_SERVER);
				if (!empty($server)){
					// 設定データを取得
					$ret = $this->db->getServerById($server, $row);
					if ($ret){
						$serverName = 'サーバ名：' . $row['ts_name'];// サーバ名
						echo '<div align="left" style="float:left;padding-left:30px;"><label>' . convertToHtmlEntity($serverName) . '</label></div>';
					}
				}
				// タブ形式以外のときは「閉じる」ボタンを表示
				if ($openBy != 'tabs') echo '<div align="right"><input type="button" class="button" value="閉じる" onclick="window.close();" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>' . M3_NL;
			}
		}
		echo '<!-- Widget Start -->' . M3_NL;
	}
	/**
	 * Widget単体起動用のタグを閉じる
	 *
	 * @param string $cmd		起動コマンド
	 */
	function endWidget($cmd)
	{
		// ウィジェット単体表示のときのみ出力
		if (!$this->showWidget) return;
		
		echo '<!-- Widget End -->' . M3_NL;
		
		// ##### ウィジェットからの指定による処理 #####
		if ($this->updateParentWindow){			// 親ウィンドウ再描画のとき
			echo '<script type="text/javascript">' . M3_NL;
			echo '//<![CDATA[' . M3_NL;
			echo '$(function(){' . M3_NL;
			if ($cmd == M3_REQUEST_CMD_CONFIG_WIDGET){		// ウィジェット詳細設定画面のとき
				echo str_repeat(M3_INDENT_SPACE, 1) . 'm3UpdateParentWindowByConfig(' . $this->updateDefSerial . ');' . M3_NL;// 更新する項目のページ定義シリアル番号
			} else if ($cmd == M3_REQUEST_CMD_DO_WIDGET){			// ウィジェット単体実行のとき
				echo str_repeat(M3_INDENT_SPACE, 1) . 'm3UpdateParentWindow();' . M3_NL;
			}
			echo '});' . M3_NL;
			echo '//]]>' . M3_NL;
			echo '</script>' . M3_NL;
		}
		
		echo '</body>' . M3_NL;
		echo '</html>' . M3_NL;
	}
	/**
	 * Widget単体RSS出力用のHTMLのヘッダ部(headタグ)出力
	 *
	 * Widgetの出力方法は、以下のパターンがある
	 *  ・HTMLヘッダ付加 - Widget単体で画面出力するためにHTMLヘッダを付加するパターン
	 *  ・HTMLヘッダなし - Wiget単体のタグ出力のみのパターン
	 *
	 * @param string $cmd		起動コマンド
	 */
	function startWidgetRss($cmd)
	{
	}
	/**
	 * Widget単体RSS出力用のタグを閉じる
	 *
	 * @param string $cmd			起動コマンド
	 * @param string $rssContent	RSS配信内容
	 */
	function endWidgetRss($cmd, $rssContent)
	{
		global $gEnvManager;
		
		// ページ作成中断のときは終了
		if ($this->isAbort) return;
		
		echo '<?xml version="1.0" encoding="' . M3_HTML_CHARSET . '" ?>' . M3_NL;
		
		// RSSチャンネルデータ取得
		$lang	= $gEnvManager->getCurrentLanguage();
		$date	= getW3CDate();		// RSS1.0用日付
		$copyright = $gEnvManager->getSiteCopyRight();		// 著作権
		$title	= $this->rssChannel['title'];				// タイトル
		$link	= $this->rssChannel['link'];				// RSS取得用URL
		$desc	= $this->rssChannel['description'];			// 説明
		$seq	= $this->rssChannel['seq'];					// 項目の並び順(URL)
		
		switch ($this->rssVersion){					// RSSバージョン
			case '1.0':
			default:
				echo '<rdf:RDF xmlns="http://purl.org/rss/1.0/" ';
				echo 'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ';
				echo 'xmlns:dc="http://purl.org/dc/elements/1.1/" ';
				echo 'xml:lang="' . $lang . '">' . M3_NL;
				echo '<channel rdf:about="' . convertUrlToHtmlEntity($link) . '">' . M3_NL;
  				echo '<title>' . convertToHtmlEntity($title) . '</title>' . M3_NL;
				echo '<link>' . convertUrlToHtmlEntity($link) . '</link>' . M3_NL;		// 「convertUrlToHtmlEntity」が必要
				echo '<description>' . convertToHtmlEntity($desc) . '</description>' . M3_NL;
				echo '<dc:language>' . $lang . '</dc:language>' . M3_NL;
				if (!empty($copyright)) echo '<dc:rights>' . convertToHtmlEntity($copyright) . '</dc:rights>' . M3_NL;
				echo '<dc:date>' . $date . '</dc:date>' . M3_NL;
				echo '<items>' . M3_NL;
				if (count($seq) > 0){
					echo str_repeat(M3_INDENT_SPACE, 1) . '<rdf:Seq>' . M3_NL;
					for ($i = 0; $i < count($seq); $i++){
						echo str_repeat(M3_INDENT_SPACE, 2) . '<rdf:li rdf:resource="' . convertUrlToHtmlEntity($seq[$i]) . '" />' . M3_NL;
					}
					echo str_repeat(M3_INDENT_SPACE, 1) . '</rdf:Seq>' . M3_NL;
				}
				echo '</items>' . M3_NL;
				echo '</channel>' . M3_NL;
				echo $rssContent;
				echo '</rdf:RDF>' . M3_NL;
				break;
			case '2.0':
				break;
		}
		
		// HTTPレスポンスヘッダ設定
		header("Content-type: text/xml; charset=utf-8");
	}
	/**
	 * 直サーバ接続時のXML出力用のHTMLのヘッダ部(headタグ)出力
	 *
	 * @param string $cmd		起動コマンド
	 * @return					なし
	 */
	function startWidgetXml($cmd)
	{
		// HTTPレスポンスヘッダ
		//header("Content-type: text/xml; charset=utf-8");
	}
	/**
	 * 直サーバ接続時のXML出力終了
	 *
	 * @param string $cmd		起動コマンド
	 * @return					なし
	 */
	function endWidgetXml()
	{
	}
	/**
	 * 携帯用ドキュメントタイプ出力
	 *
	 * @return string				ドキュメントタイプ出力
	 */
	function getMobileDocType()
	{
		global $gEnvManager;
		global $gInstanceManager;
		global $gRequestManager;
		
		$docTypeStr = '';		// 出力するDocType
		$agent = $gInstanceManager->getMobileAgent();
		if ($agent->isDoCoMo()){	// ドコモ端末のとき
			$htmlVer = $agent->getHTMLVersion();
			switch ($htmlVer){
				case '4.0':
					$docTypeStr = '<!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/1.0) 1.0//EN" "i-xhtml_4ja_10.dtd">';
					break;
				case '5.0':
					$docTypeStr = '<!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/1.1) 1.0//EN" "i-xhtml_4ja_10.dtd">';
					break;
				case '6.0':
					$docTypeStr = '<!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/2.0) 1.0//EN" "i-xhtml_4ja_10.dtd">';
					break;
				case '7.0':
					$docTypeStr = '<!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/2.1) 1.0//EN" "i-xhtml_4ja_10.dtd">';
					break;
				case '7.1':
					$docTypeStr = '<!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/2.2) 1.0//EN" "i-xhtml_4ja_10.dtd">';
					break;
				case '7.2':
					$docTypeStr = '<!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/2.3) 1.0//EN" "i-xhtml_4ja_10.dtd">';
					break;
				default:
					if (preg_match("/^DoCoMo\/1\.0/i", $gRequestManager->trimServerValueOf('HTTP_USER_AGENT'))){		// mova端末のとき
						// mova端末のときはドキュメントタイプなしにすると画面表示可能
						return '';
					}
					break;
			}
		} else if ($agent->isEZweb()){	// au端末のとき
			if ($agent->isWAP2()){
				$docTypeStr = '<!DOCTYPE html PUBLIC "-//OPENWAVE//DTD XHTML 1.0//EN" "http://www.openwave.com/DTD/xhtml-basic.dtd">';
			}
		} else if ($agent->isSoftBank()){	// ソフトバンク端末のとき
			if ($agent->isTypeW() || $agent->isType3GC()){
				$docTypeStr = '<!DOCTYPE html PUBLIC "-//J-PHONE//DTD XHTML Basic 1.0 Plus//EN" "xhtml-basic10-plus.dtd">';
			}
		}
		if ($gEnvManager->getIsMobileSite()){		// 携帯用サイトへのアクセスの場合
			echo '<?xml version="1.0" encoding="' . $gEnvManager->getMobileCharset() . '" ?>' . M3_NL;
		} else {
			echo '<?xml version="1.0" encoding="' . M3_HTML_CHARSET . '" ?>' . M3_NL;
		}
		if (empty($docTypeStr)) $docTypeStr = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
		echo $docTypeStr . M3_NL;
	}
	/**
	 * デフォルトのXML宣言取得
	 *
	 * @return string	XML宣言
	 */
	function getDefaultXmlDeclaration()
	{
		return '<?xml version="1.0" encoding="' . M3_HTML_CHARSET . '" ?>';
	}
	/**
	 * HTMLのヘッダ部(headタグ内)出力
	 *
	 * システムに共通な定義をHTMLのheadタグ内に出力する
	 * mosFunc.phpからも実行されるので、このメソッドは引数なしに固定。
	 * この関数は、以下の「形式1」または「形式2」でheadタグ内に記述する
	 *
	 * 形式1:            <!-- m3:HTMLHeader -->
	 * 形式2(old style): <?php mosShowHead(); ?>
	 */
	function getHeader()
	{
		global $gEnvManager;
		global $gRequestManager;
		
		$this->outputHead = true;				// HTMLヘッダ出力を行ったかどうか
		
		// 実行コマンドを取得
		$cmd = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		
		// ######### 携帯用サイトの場合は別にヘッダを作成する #########
		if ($gEnvManager->getIsMobileSite()){
			// キャラクターセット
			echo '<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=' . $gEnvManager->getMobileCharset() . '" />' . M3_NL;

			// キャッシュを保存させない
			echo '<meta http-equiv="Pragma" content="no-cache" />' . M3_NL;
			echo '<meta http-equiv="Cache-Control" content="no-cache" />' . M3_NL;
			echo '<meta http-equiv="Expires" content="-1" />' . M3_NL;
		
			// サイト構築エンジン
			echo '<meta name="generator" content="' . M3_SYSTEM_NAME . ' ver.' . M3_SYSTEM_VERSION . ' - ' . M3_SYSTEM_DESCRIPTION . '" />' . M3_NL;
		} else {		// PC用サイト、管理用サイト、スマートフォン用サイトのとき
			// ********** メタタグの設定 **********
			echo '<meta http-equiv="content-script-type" content="text/javascript" />' . M3_NL;
			echo '<meta http-equiv="content-style-type" content="text/css" />' . M3_NL;
	
			// キャラクターセット
			if ($gEnvManager->getIsSmartphoneSite()){		// スマートフォン用サイトのときはHTML5で設定
				echo '<meta http-equiv="content-type" content="text/html; charset=' . M3_HTML_CHARSET .'" />' . M3_NL;
			} else {
				echo '<meta http-equiv="content-type" content="application/xhtml+xml; charset=' . M3_HTML_CHARSET .'" />' . M3_NL;
			}
		
			// 基準ディレクトリの指定
			if ($cmd == M3_REQUEST_CMD_SHOW_POSITION ||				// 表示位置を表示するとき
				$cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){	// 表示位置を表示するとき(ウィジェット付き)
			
				if ($gEnvManager->getUseSslAdmin()){
					$rootUrl = $gEnvManager->getSslRootUrl();
				} else {
					$rootUrl = $gEnvManager->getRootUrl();
				}
				echo '<base href="' . $rootUrl . '/" />' . M3_NL;
			}
		}
		echo self::HEAD_TAGS;			// HTMLヘッダの埋め込みデータ
	}
	/**
	 * HTMLヘッダ出力文字列の取得
	 *
	 * @return string		HTMLヘッダ出力文字列
	 */
	function getHeaderOutput()
	{
		global $gEnvManager;
		global $gRequestManager;
		
		$replaceStr = '';		// 変換文字列
				
		if (defined('M3_STATE_IN_INSTALL')){		// インストール時のヘッダ出力
			// タイトルの作成
			$title = '';
			if (count($this->headSubTitle) > 0) $title = htmlspecialchars(trim($this->headSubTitle[0]));
			
			// ********** メタタグの設定 **********
			$replaceStr .= '<title>' . $title . '</title>' . M3_NL;
			return $replaceStr;
		}
		
		// 実行コマンドを取得
		$cmd = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		$task = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_TASK);
		
		// テンプレートの情報を取得
		$cleanType = 0;		// テンプレートクリーンタイプ
		if ($this->db->getTemplate($gEnvManager->getCurrentTemplateId(), $templateRow)){
			$cleanType = $templateRow['tm_clean_type'];
		}
		
		// URLの作成
		$isSslPage = false;
		if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
			// 管理画面のSSL状態を参照
			if ($gEnvManager->getUseSslAdmin()) $isSslPage = true;		// 管理画面でSSLを使用するとき
		} else {
			$isSslPage = $this->isSslPage($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId());
		}
		if ($isSslPage){
			$rootUrl = $gEnvManager->getSslRootUrl();
			$scriptsUrl = $gEnvManager->getSslScriptsUrl();		// スクリプト読み込み用パス
			$widgetsUrl = $gEnvManager->getSslWidgetsUrl();		// ウィジェット格納パス
			$templatesUrl = $gEnvManager->getSslTemplatesUrl();	// テンプレート読み込み用パス
		} else {
			$rootUrl = $gEnvManager->getRootUrl();
			$scriptsUrl = $gEnvManager->getScriptsUrl();		// スクリプト読み込み用パス
			$widgetsUrl = $gEnvManager->getWidgetsUrl();		// ウィジェット格納パス
			$templatesUrl = $gEnvManager->getTemplatesUrl();	// テンプレート読み込み用パス
		}
			
		// タイトルの設定
		if (!$this->showWidget){// 単体実行以外のとき
			if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスの場合
				// 画面タイトル
				$siteName = $gEnvManager->getSiteName();
				if (empty($siteName)) $siteName = self::DEFAULT_SITE_NAME;
				$siteName .= ' - ' . self::DEFAULT_ADMIN_TITLE;
				$replaceStr .= '<title>' . $siteName . '</title>' . M3_NL;
			} else {			// 管理画面以外の画面へのアクセスの場合
				// 画面タイトル
				$titleItemCount = 0;		// タイトル項目数
				$defaultTitle = trim($this->gSystem->getSiteDef(M3_TB_FIELD_SITE_TITLE));
				if (!empty($defaultTitle)) $titleItemCount++;
				if (!empty($this->headSubTitle)){		// サブタイトルが設定されているとき
					$titleItemCount += count($this->headSubTitle);
				}
				// タイトルフォーマットを取得
				$title = '';
				if ($titleItemCount > 0){
					$format = $this->gSystem->getSystemConfig(self::CONFIG_KEY_HEAD_TITLE_FORMAT);
					if (empty($format)){
						$title = htmlspecialchars($defaultTitle);
					} else {
						$formats = explode(';', $format);
						$titleItemCount = ($titleItemCount > count($formats)) ? count($formats) : $titleItemCount;
						$title = $formats[$titleItemCount -1];
						$number = 1;
						if (!empty($defaultTitle)){
							$title = str_replace('$1', htmlspecialchars($defaultTitle), $title);
							$number++;
						}
						for ($i = 0; $i < count($this->headSubTitle); $i++){
							$key = '$' . $number;
							$value = htmlspecialchars(trim($this->headSubTitle[$i]));
							$title = str_replace($key, $value, $title);
							$number++;
						}
					}
				}
				if (!empty($title)) $replaceStr .= '<title>' . $title . '</title>' . M3_NL;

				// サイトの説明
				if (!empty($this->headDescription)) $replaceStr .= '<meta name="description" content="' . htmlspecialchars($this->headDescription) . '" />' . M3_NL;
		
				// 検索エンジン用キーワード
				if (!empty($this->headKeywords)) $replaceStr .= '<meta name="keywords" content="' . htmlspecialchars($this->headKeywords) . '" />' . M3_NL;
			}
		}
		
		// ##### PC用URLと携帯用URLのアクセス別に処理 #####
		if ($gEnvManager->getIsMobileSite()){		// 携帯用URLのとき
		} else {			// PC用URLまたはスマートフォン用URLのとき
			// ##### テンプレート情報に応じた処理 #####
			// テンプレートクリーンが必要な場合はJQueryを追加
			if ($cleanType != 0) $this->addScriptFile($this->selectedJQueryFilename);		// JQueryスクリプト追加

			// 検索ロボットへの指示
			$robots = htmlspecialchars(trim($this->gSystem->getSiteDef(M3_TB_FIELD_SITE_ROBOTS)));
			if (!empty($robots)){
				$replaceStr .= '<meta name="robots" content="' . $robots . '" />' . M3_NL;
			}
		
			// サイト構築エンジン
			$replaceStr .= '<meta name="generator" content="' . M3_SYSTEM_NAME . ' ver.' . M3_SYSTEM_VERSION . ' - ' . M3_SYSTEM_DESCRIPTION . '" />' . M3_NL;		

			// Faviconの読み込み
			$templateId = $gEnvManager->getCurrentTemplateId();
			if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
				// テンプレートのFaviconがない場合はシステムのデフォルトのFaviconを使用
				$faviconPath = $gEnvManager->getTemplatesPath() . '/' . $templateId . self::DEFAULT_FAVICON_FILE;
				if (file_exists($faviconPath)){		// ファイルが存在しているとき
					$faviconFile = $templatesUrl . '/' . $templateId . self::DEFAULT_FAVICON_FILE;
					$replaceStr .= '<link rel="shortcut icon" href="' . $faviconFile .'" />' . M3_NL;
				} else {
					// 管理画面のアイコンを設定
					$faviconPath = $gEnvManager->getSystemRootPath() . self::DEFAULT_ADMIN_FAVICON_FILE;
					if (file_exists($faviconPath)){		// ファイルが存在しているとき
						$faviconFile = $rootUrl . self::DEFAULT_ADMIN_FAVICON_FILE;
						$replaceStr .= '<link rel="shortcut icon" href="' . $faviconFile .'" />' . M3_NL;
					}
				}
			} else {
				$faviconPath = $gEnvManager->getTemplatesPath() . '/' . $templateId . self::DEFAULT_FAVICON_FILE;
				if (file_exists($faviconPath)){		// ファイルが存在しているとき
					$faviconFile = $templatesUrl . '/' . $templateId . self::DEFAULT_FAVICON_FILE;
					$replaceStr .= '<link rel="shortcut icon" href="' . $faviconFile .'" />' . M3_NL;
				}
			}
			// ##### Ajaxライブラリの読み込み #####
			if (!$gEnvManager->isAdminDirAccess()){		// 通常画面へのアクセスのとき
				if ($this->db->isExistsWidgetWithAjax($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId())){// Ajaxライブラリを使用しているウィジェットがあるときは追加
					$this->addScriptFile($this->selectedJQueryFilename);		// デフォルトAjaxライブラリ追加
					$this->addScriptFile(self::M3_OPTION_SCRIPT_FILENAME);	// Magic3のオプションライブラリ追加
				}
			}
				
			// ##### 共通ライブラリの読み込み #####
			if (!$this->showWidget){// 単体実行以外のとき
				$this->db->getWidgetsIdWithLib($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId(), $rows);
				for ($i = 0; $i < count($rows); $i++){
					$this->addScript($task, trim($rows[$i]['wd_add_script_lib']));
				}
			}

			// ##### 共通CSS読み込み #####
			if ($this->isEditMode){			// 一般画面編集モード
				$cssURL = $scriptsUrl . self::M3_EDIT_CSS_FILE;
				$replaceStr .=  '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
			}
			if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
				//if ($gEnvManager->isSystemAdmin()){		// 管理者権限がある場合のみ有効
				if ($gEnvManager->isSystemManageUser()){		// システム運用権限がある場合のみ有効
					// 管理機能用共通ライブラリのCSSの読み込み
					$count = count($this->defaultAdminCssFiles);
					for ($i = 0; $i < $count; $i++){
						// CSSへのURLを作成
						$cssURL = $scriptsUrl . '/' . $this->defaultAdminCssFiles[$i];
						$replaceStr .=  '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
					}
				}
			} else {
				// 共通ライブラリのCSSの読み込み
				$count = count($this->defaultCssFiles);
				for ($i = 0; $i < $count; $i++){
					// CSSへのURLを作成
					$cssURL = $scriptsUrl . '/' . $this->defaultCssFiles[$i];
					$replaceStr .=  '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
				}
			}
			
			// ##### 表示モードによるCSS読み込み #####
			// ウィジェット付きポジション画面は管理画面のアクセスではない
			if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
				// ウィジェット操作用CSS
				$cssURL = $scriptsUrl . self::M3_ADMIN_WIDGET_CSS_FILE;
				$replaceStr .=  '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . 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)
							&& strncmp($file, '_', 1) != 0){		// 「_」で始まる名前のファイルは読み込まない
					
							// CSSへのURLを作成
							$cssURL = $widgetsUrl . '/' . $rows[$i]['wd_id'] . '/' . M3_DIR_NAME_CSS . '/' . $file;
							$replaceStr .=  '<link rel="stylesheet" type="text/css" href="' . $cssURL . '" />' . M3_NL;
						}
					}
					$dir->close();
				}
			}
			// ウィジェットからの追加のCSS読み込み
			$count = count($this->headCssFiles);
			for ($i = 0; $i < $count; $i++){
				$cssUrl = $this->headCssFiles[$i];
				if ($isSslPage) $cssUrl = str_replace('http://', 'https://', $cssUrl);			// SSL化が必要なときは変換
				$replaceStr .=  '<link rel="stylesheet" type="text/css" href="' . $cssUrl . '" />' . M3_NL;
			}

			// ##### RSS配信情報の読み込み #####
			$count = count($this->headRssFiles);
			for ($i = 0; $i < $count; $i++){
				$rssUrl = $this->headRssFiles[$i]['href'];// リンク先URL
				$rssTitle = $this->headRssFiles[$i]['title'];// タイトル
				$replaceStr .=  '<link rel="alternate" type="application/rss+xml" title="' . $rssTitle . '" href="' . convertUrlToHtmlEntity($rssUrl) . '" />' . M3_NL;
			}
														
			// ##### 共通Javascriptの読み込み #####
			if ($gEnvManager->isAdminDirAccess()){		// 管理画面へのアクセスのとき
				//if ($gEnvManager->isSystemAdmin()){		// 管理者権限がある場合のみ有効
				if ($gEnvManager->isSystemManageUser()){		// システム運用権限がある場合のみ有効
					// 管理画面用の共通スクリプトを読み込む
					$count = count($this->defaultAdminScriptFiles);
					for ($i = 0; $i < $count; $i++){
						$scriptFilename = $this->defaultAdminScriptFiles[$i];

						// スクリプトをキャッシュ保存しない場合は、パラメータを付加
						$scriptURL = $scriptsUrl . '/' . $scriptFilename;
						if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
						$replaceStr .=  '<script type="text/javascript" src="' . $scriptURL . '"></script>' . M3_NL;
					}
					if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示のときは、ウィジェット操作ライブラリを読み込む
						// wigetのドラッグドロップ用
						$scriptURL = $scriptsUrl . '/' . self::M3_ADMIN_WIDGET_SCRIPT_FILENAME;
						if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
						$replaceStr .=  '<script type="text/javascript" src="' . $scriptURL . '"></script>' . M3_NL;
						// キー割付用
						//$scriptURL = $scriptsUrl . '/' . ScriptLibInfo::JQUERY_JSHOTKEYS_FILENAME;
						//if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();// スクリプトをキャッシュ保存しない場合は、パラメータを付加
						//$replaceStr .=  '<script type="text/javascript" src="' . $scriptURL . '"></script>' . M3_NL;
					}
				}
			} else {			// 通常画面
				// ウィジェット単体実行でウィンドウを持つ場合の追加スクリプト
				$openBy = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPEN_BY);		// ウィンドウオープンタイプ
				if ($cmd == M3_REQUEST_CMD_DO_WIDGET &&	!empty($openBy)){						// ウィジェット単体実行でウィンドウを持つとき
					$this->addScript('', ScriptLibInfo::LIB_FCKEDITOR);// FCKEditorスクリプト追加
					$this->addScriptFile(self::M3_PLUS_SCRIPT_FILENAME);		// 一般画面追加用スクリプト追加(PLUSライブラリを追加する場合はFCKEditorも使用可能にする)
					$this->addScriptFile(self::M3_OPTION_SCRIPT_FILENAME);	// Magic3のオプションライブラリ追加
					$this->addScript('', ScriptLibInfo::LIB_JQUERY_CLUETIP);// HELP用スクリプト追加
				}
				
				$count = count($this->defaultScriptFiles);
				for ($i = 0; $i < $count; $i++){
					$defaultScriptFile = $this->defaultScriptFiles[$i];
					
					// ##### jQueryMobileスクリプトを追加する場合は直前に初期化スクリプトを追加 #####
					if ($defaultScriptFile == $this->selectedJQueryMobileFilename){
						if (count($this->headPreMobileScript) > 0){
							$replaceStr .= '<script type="text/javascript">' . M3_NL;
							$replaceStr .= '//<![CDATA[' . M3_NL;
							for ($j = 0; $j < count($this->headPreMobileScript); $j++){
								$replaceStr .= $this->headPreMobileScript[$j];
							}
							$replaceStr .= M3_NL;
							$replaceStr .= '//]]>' . M3_NL;
							$replaceStr .= '</script>' . M3_NL;
						}
					}
					
					// スクリプトのURLを修正
					if (strncasecmp($defaultScriptFile, 'http://', 7) == 0 || strncasecmp($defaultScriptFile, 'https://', 8) == 0){
						$scriptURL = $defaultScriptFile;
					} else {
						$scriptURL = $scriptsUrl . '/' . $defaultScriptFile;
					}

					// スクリプトをキャッシュ保存しない場合は、パラメータを付加
					if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
					$replaceStr .=  '<script type="text/javascript" src="' . $scriptURL . '"></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)
							&& strncmp($file, '_', 1) != 0){		// 「_」で始まる名前のファイルは読み込まない
						
							// スクリプトへのURLを作成
							$scriptURL = $widgetsUrl . '/' . $rows[$i]['wd_id'] . '/' . M3_DIR_NAME_SCRIPTS . '/' . $file;
							// スクリプトをキャッシュ保存しない場合は、パラメータを付加
							if (!$this->hasScriptCache) $scriptURL .= $this->getCacheParam();
							$replaceStr .=  '<script type="text/javascript" src="' . $scriptURL . '"></script>' . M3_NL;
						}
					}
					$dir->close();
				}
			}
			// ウィジェットからの追加のCSS読み込み
			$count = count($this->headScriptFiles);
			for ($i = 0; $i < $count; $i++){
				$scriptUrl = $this->headScriptFiles[$i];
				if ($isSslPage) $scriptUrl = str_replace('http://', 'https://', $scriptUrl);			// SSL化が必要なときは変換
		
				// スクリプトをキャッシュ保存しない場合は、パラメータを付加
				if (!$this->hasScriptCache) $scriptUrl .= $this->getCacheParam();
				$replaceStr .=  '<script type="text/javascript" src="' . $scriptUrl . '"></script>' . M3_NL;
			}
			
			// 設定値取得
			$openType = $this->gSystem->getSystemConfig(self::CF_CONFIG_WINDOW_OPEN_TYPE);// ウィジェット設定画面のウィンドウ表示タイプ(0=別ウィンドウ、1=タブ)
			
			// JavaScriptグローバル変数の設定
			//$replaceStr .= '<script type="text/javascript">' . M3_NL;
			//$replaceStr .= '<!--' . M3_NL;
			$replaceStr .= '<script type="text/javascript">' . M3_NL;
			$replaceStr .= '//<![CDATA[' . M3_NL;
			$replaceStr .= '// Magic3 Global values' . M3_NL;
			$replaceStr .= 'var M3_ROOT_URL = "' . $rootUrl . '";' . M3_NL;		// システムルートURL
			
			if ($gEnvManager->isAdminDirAccess() && $gEnvManager->isSystemManageUser()){		// 管理画面へのアクセス、システム運用権限があり
				// 管理画面のオープン設定
				$replaceStr .= 'var M3_DEFAULT_ADMIN_URL="' . $gEnvManager->getDefaultAdminUrl() . '";' . M3_NL;		// 管理機能URL
				if ($openType != '') $replaceStr .= 'var M3_CONFIG_WINDOW_OPEN_TYPE = ' . $openType . ';' . M3_NL;
				
				// ページID、ページサブID
				$replaceStr .= 'var M3_PAGE_ID = "' . $gEnvManager->getCurrentPageId() . '";' . M3_NL;
				$replaceStr .= 'var M3_PAGE_SUB_ID = "' . $gEnvManager->getCurrentPageSubId() . '";' . M3_NL;
				
				// FCKEditor拡張プラグイン用の定義
				$googleMapsKey = $this->gSystem->getSystemConfig(self::CF_GOOGLE_MAPS_KEY);		// Googleマップ利用キー
				if (!empty($googleMapsKey)) $replaceStr .= 'var M3_GOOGLE_MAPS_KEY="' . $googleMapsKey . '";' . M3_NL;		// システムルートURL

				if ($cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET){		// ウィジェット付きポジション表示
					$pageId = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_DEF_PAGE_ID);		// ページID
					$pageSubId = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_DEF_PAGE_SUB_ID);// ページサブID
			
					if (!empty($task)){		// 戻りタスクが設定されているときのみ最大化可能
						$replaceStr .= 'function gobackPagedef(){' . M3_NL;
						$replaceStr .= '    window.location.href = "' . $gEnvManager->getDefaultAdminUrl() . '?pageid=' . $pageId . '&pagesubid=' . $pageSubId . '&task=' . $task . '";' . M3_NL;
						$replaceStr .= '}' . M3_NL;
						$replaceStr .= '$(document).ready(function(){' . M3_NL;
						$replaceStr .= '    jQuery.hotkeys.add("esc", function(){' . M3_NL;
						$replaceStr .= '        gobackPagedef();' . M3_NL;
						$replaceStr .= '    });' . M3_NL;
						$replaceStr .= '});' . M3_NL;
					}
				}
			} else if ($this->isPageEditable){		// 一般画面ページ編集可能モードのとき
				$replaceStr .= 'var M3_DEFAULT_ADMIN_URL="' . $gEnvManager->getDefaultAdminUrl() . '";' . M3_NL;		// 管理機能URL
				if ($openType != '') $replaceStr .= 'var M3_CONFIG_WINDOW_OPEN_TYPE = ' . $openType . ';' . M3_NL;
				
				// ページID、ページサブID
				$replaceStr .= 'var M3_PAGE_ID = "' . $gEnvManager->getCurrentPageId() . '";' . M3_NL;
				$replaceStr .= 'var M3_PAGE_SUB_ID = "' . $gEnvManager->getCurrentPageSubId() . '";' . M3_NL;
			}
			
			// ##### パネルメニュー(一般画面と管理画面の切り替え等)の表示 #####
			// PC用、携帯用、スマートフォン用画面とウィジェット付きポジションの管理画面時に表示
			if (($gEnvManager->isAdminDirAccess() && $cmd == M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET) ||		// 管理画面(ウィジェット付きポジション表示)のとき
				(!$gEnvManager->isAdminDirAccess() &&							// 一般用画面のとき
					$cmd != M3_REQUEST_CMD_DO_WIDGET &&							// ウィジェット単体実行でない
					$cmd != M3_REQUEST_CMD_RSS)){								// RSS配信でない
				if ($gEnvManager->isSystemAdmin()){		// 管理者権限がある場合のみ有効
					// トップメニュー項目作成
					$linkStr = '';
					$adminTag = '';		// 管理画面ボタン
					$editTag = '';		// 編集ボタン
					$logoutTag = '';		// ログアウトボタン
					
/*					// 管理画面ボタン
					$titleStr = '管理画面';
					$linkUrl = $gEnvManager->getDefaultAdminUrl();
					$linkStr .= '<div align="left" style="float:left;"><a href="' . convertUrlToHtmlEntity($linkUrl) . '">' . $titleStr . '</a>&nbsp;&nbsp;&nbsp;&nbsp;</div>';
					
					// ログアウトボタン
					$titleStr = 'ログアウト';
					if ($gEnvManager->isAdminDirAccess()){		// 管理画面の場合
						$linkUrl = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_BACKUP_URL);		// 退避していたURLを取得
						if (empty($linkUrl)) $linkUrl = $gEnvManager->getDefaultUrl();
					} else {
						$linkUrl = $gEnvManager->getCurrentRequestUri();
					}
					$linkUrl = createUrl($linkUrl, M3_REQUEST_PARAM_OPERATION_COMMAND . '=' . M3_REQUEST_CMD_LOGOUT);
					$linkStr .= '<div align="left" style="float:left;"><a href="' . convertUrlToHtmlEntity($linkUrl) . '">' . $titleStr . '</a>&nbsp;&nbsp;&nbsp;&nbsp;</div>';
					
					// 編集ボタン
					if ($gEnvManager->isAdminDirAccess()){		// 管理画面の場合
						$titleStr = '編集終了';
						$linkUrl = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_BACKUP_URL);		// 退避していたURLを取得
						if (empty($linkUrl)) $linkUrl = $gEnvManager->getDefaultUrl();
					} else {
						$titleStr = '編集';
						$linkUrl  = $gEnvManager->getDefaultAdminUrl() . '?' . M3_REQUEST_PARAM_OPERATION_COMMAND . '=' .M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET;
						$linkUrl .= '&' . M3_REQUEST_PARAM_DEF_PAGE_ID . '=' . $gEnvManager->getCurrentPageId();
						$linkUrl .= '&' . M3_REQUEST_PARAM_DEF_PAGE_SUB_ID . '=' . $gEnvManager->getCurrentPageSubId();
						$linkUrl .= '&' . M3_REQUEST_PARAM_BACKUP_URL . '=' . urlencode($gEnvManager->getCurrentRequestUri());			// URL退避用
					}
					$linkStr .= '<div align="right" width="50%"><a href="' . convertUrlToHtmlEntity($linkUrl) . '">' . $titleStr . '</a>&nbsp;&nbsp;</div>';
					
					// 初期化スクリプトを設定
					$this->initScript .= '    $("body").append(\'<div id="m3editmenu" style="position:absolute;top:0;left:0;width:100%;padding:0;background-color:black;">' . $linkStr . '</div>\');' . M3_NL;
					$this->initScript .= '    $("#m3editmenu").fadeTo("fast", 0.6);' . M3_NL;
					$this->initScript .= '    $(window).scroll(function(){' . M3_NL;
					$this->initScript .= '        $("#m3editmenu").css("top", $(document).scrollTop());' . M3_NL;
					$this->initScript .= '    });' . M3_NL;
					*/
					if ($gEnvManager->isAdminDirAccess()){		// 管理画面(ウィジェット付きポジション表示)の場合
						// 編集ボタン
/*						$titleStr = '編集終了';
						$linkUrl = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_BACKUP_URL);		// 退避していたURLを取得
						if (empty($linkUrl)) $linkUrl = $gEnvManager->getDefaultUrl();
						$editTag = '<li><a href="' . convertUrlToHtmlEntity($linkUrl) . '">';
						$editTag .= '<img src="' . $rootUrl . self::EDIT_END_ICON_FILE . '" alt="' . $titleStr . '" title="' . $titleStr . '" /></a></li>';
						*/
						$titleStr = '編集終了';
						$linkUrl = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_BACKUP_URL);		// 退避していたURLを取得
						if (empty($linkUrl)) $linkUrl = $gEnvManager->getDefaultUrl();
						$editTag = '<div id="m3close"><a href="' . convertUrlToHtmlEntity($linkUrl) . '">';
						$editTag .= '<img src="' . $rootUrl . self::EDIT_END_ICON_FILE . '" alt="' . $titleStr . '" title="' . $titleStr . '" /></a></div>';
						$linkStr .= $editTag;
						
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 1) . 'if (window.parent && window.parent.frames.length == 0){' . M3_NL;// インラインフレームでないときパネルメニューを表示
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . '$("body").prepend(\'' . $linkStr . '\');' . M3_NL;		// appendでうまく表示できないのでprependで表示
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 1) . '}' . M3_NL;
					} else {
						// 管理画面ボタン
						$titleStr = '管理画面';
						$linkUrl = $gEnvManager->getDefaultAdminUrl();
						$adminTag = '<li><a href="' . convertUrlToHtmlEntity($linkUrl) . '">';
						$adminTag .= '<img src="' . $rootUrl . self::ADMIN_ICON_FILE . '" alt="' . $titleStr . '" title="' . $titleStr . '" /></a></li>';
					
						// 編集ボタン
						$titleStr = '編集';
						$linkUrl  = $gEnvManager->getDefaultAdminUrl() . '?' . M3_REQUEST_PARAM_OPERATION_COMMAND . '=' .M3_REQUEST_CMD_SHOW_POSITION_WITH_WIDGET;
						$linkUrl .= '&' . M3_REQUEST_PARAM_DEF_PAGE_ID . '=' . $gEnvManager->getCurrentPageId();
						$linkUrl .= '&' . M3_REQUEST_PARAM_DEF_PAGE_SUB_ID . '=' . $gEnvManager->getCurrentPageSubId();
						$linkUrl .= '&' . M3_REQUEST_PARAM_BACKUP_URL . '=' . urlencode($gEnvManager->getCurrentRequestUri());			// URL退避用
						$editTag = '<li><a href="' . convertUrlToHtmlEntity($linkUrl) . '">';
						$editTag .= '<img src="' . $rootUrl . self::EDIT_PAGE_ICON_FILE . '" alt="' . $titleStr . '" title="' . $titleStr . '" /></a></li>';
						
						// ログアウトボタン
						$titleStr = 'ログアウト';
//						if ($gEnvManager->isAdminDirAccess()){		// 管理画面の場合
//							$linkUrl = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_BACKUP_URL);		// 退避していたURLを取得
//							if (empty($linkUrl)) $linkUrl = $gEnvManager->getDefaultUrl();
//						} else {
							$linkUrl = $gEnvManager->getCurrentRequestUri();
//						}
						$linkUrl = createUrl($linkUrl, M3_REQUEST_PARAM_OPERATION_COMMAND . '=' . M3_REQUEST_CMD_LOGOUT);
						$logoutTag = '<li><a href="' . convertUrlToHtmlEntity($linkUrl) . '">';
						$logoutTag .= '<img src="' . $rootUrl . self::LOGOUT_ICON_FILE . '" alt="' . $titleStr . '" title="' . $titleStr . '" /></a></li>';
						
						$linkStr .= '<div id="m3slidemenubar">';
						$linkStr .= '<div id="m3slidemenubarpanel">';
						$linkStr .= '<ul class="menubarbuttons">';
						$linkStr .= $adminTag;
						$linkStr .= $editTag;
						$linkStr .= $logoutTag;
						$linkStr .= '</ul>';
						$linkStr .= '</div>';
						$linkStr .= '<div id="slidetrigger">';
						$linkStr .= '<a href="#" class="open">開く</a>';
						$linkStr .= '<a href="#" class="close">閉じる</a>';
						$linkStr .= '</div>';
						$linkStr .= '</div>';
					
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 1) . 'if (window.parent && window.parent.frames.length == 0){' . M3_NL;// インラインフレームでないときパネルメニューを表示
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . '$("body").append(\'' . $linkStr . '\');' . M3_NL;
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . '$("#m3slidemenubarpanel").m3SlideMenubar();' . M3_NL;
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 1) . '}' . M3_NL;
					}
				}
			}
			// 一般画面からのウィジェット操作用ツールバー
			if (!$gEnvManager->isAdminDirAccess() && 
				$cmd != M3_REQUEST_CMD_DO_WIDGET &&							// ウィジェット単体実行でない
				$cmd != M3_REQUEST_CMD_RSS){								// RSS配信でない
				if ($gEnvManager->isSystemManageUser()){		// 一般用画面で管理者権限がある場合のみ有効
					$this->initScript .= M3_INDENT_SPACE . '$(\'body\').append(\'<div id="m3editwidget"></div>\');' . M3_NL;
					//$this->initScript .= M3_INDENT_SPACE . '$("div.m3_widget").cluetip({local:true, positionBy:"fixed", topOffset:10, width:50, showTitle:false, sticky:true, mouseOutClose:true, closeText:"",' . M3_NL;
					$this->initScript .= M3_INDENT_SPACE . '$(\'div.m3_widget\').cluetip({local:true, positionBy:"fixed", topOffset:10, leftOffset:-100, width:50, showTitle:false, sticky:true, mouseOutClose:true, closeText:"",' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . 'fx:{open:\'fadeIn\', openSpeed:\'fast\'},' . M3_NL;
					//$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . 'fx:{open:\'fadeIn\', openSpeed:2000},' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . 'onActivate: function(e){' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'var attrs = m3_splitAttr($(e).attr(\'m3\'));' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'var widgetId = attrs[\'widgetid\'];' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'var serialNo = attrs[\'serial\'];' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'var configId = attrs[\'configid\'];' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'var useconfig = attrs[\'useconfig\'];' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'var html = \'\';' . M3_NL;
					if ($gEnvManager->isSystemAdmin()){		// 位置調整は管理者権限がある場合のみ有効(管理ウィジェットの機能のため)
						$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 
											'html += \'<a href="javascript:void(0);" onclick="m3ShowAdjustWindow(\' + configId + \', \' + serialNo + \', M3_PAGE_ID, M3_PAGE_SUB_ID);return false;" >' .
											'<img src="' . $rootUrl . self::ADJUST_ICON_FILE . '" alt="タイトル・位置調整" title="タイトル・位置調整" border="0" style="margin-left:4px;" /></a>\';' . M3_NL;
					}
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'if (useconfig == 1){' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 4) . 
										'html += \'<a href="javascript:void(0);" onclick="m3ShowConfigWindow(\\\'\' + widgetId + \'\\\', \' + configId + \', \' + serialNo + \');return false;" >' .
										'<img src="' . $rootUrl . self::CONFIG_ICON_FILE . '" alt="ウィジェット設定" title="ウィジェット設定" border="0" style="margin-left:4px;" /></a>\';' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . '}' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . 'if (html == \'\'){' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 4) . 'return false;' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . '} else {' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 4) . '$(\'#m3editwidget\').html(html);' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 4) . 'return true;' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 3) . '}' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . '}' . M3_NL;
					$this->initScript .= M3_INDENT_SPACE . '});' . M3_NL;
					
					// ウィジェットボーダーハイライト
					$this->initScript .= M3_INDENT_SPACE . '$(\'div.m3_widget\').hover(function(){' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . '$(this).addClass(\'m3_widget_highlight\');' . M3_NL;
					$this->initScript .= M3_INDENT_SPACE . '}, function(){' . M3_NL;
					$this->initScript .= str_repeat(M3_INDENT_SPACE, 2) . '$(this).removeClass(\'m3_widget_highlight\');' . M3_NL;
					$this->initScript .= M3_INDENT_SPACE . '});' . M3_NL;
				}
			}
			// ポップアップメッセージがある場合は表示
			if (!empty($this->popupMsg)){
				$replaceStr .=  'alert("' . $this->popupMsg . '");' . M3_NL;
			}
			// テンプレートに応じた処理
			if ($cleanType == 1){
				// HTMLのクリーン処理が必要なときはコードを埋め込む
				$this->initScript .= '    $(\'.PostHeaderIcons\').remove();' . M3_NL;// 不要なアイコン表示タグの削除
				$this->initScript .= '    $(\'.PostMetadataHeader\').each(function(i){' . M3_NL;
				$this->initScript .= '        if ($(this).text().trim() == \'\') $(this).remove();' . M3_NL;
				$this->initScript .= '    });' . M3_NL;
			}
			// 初期処理用スクリプト埋め込み
			if (!empty($this->initScript)){
				$replaceStr .= '$(function(){' . M3_NL;
				$replaceStr .= $this->initScript;
				$replaceStr .= '});' . M3_NL;
			}
			
			//$replaceStr .= '// -->' . M3_NL;
			//$replaceStr .= '</script>' . M3_NL;
			$replaceStr .= '//]]>' . M3_NL;
			$replaceStr .= '</script>' . M3_NL;

			// HEADタグに埋め込むCSS,JavaScript,任意文字列
			if (count($this->headCss) > 0){
				// CSSの場合は全体をstyleタグで囲む
				$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 . '//-->' . M3_NL;
				$replaceStr .= '</style>' . M3_NL;
			}
			if (count($this->headScript) > 0){
				// JavaScriptの場合は全体をscriptタグで囲む
				//$replaceStr .= '<script type="text/javascript">' . M3_NL;
				//$replaceStr .= '<!--' . M3_NL;
				$replaceStr .= '<script type="text/javascript">' . M3_NL;
				$replaceStr .= '//<![CDATA[' . M3_NL;
				for ($i = 0; $i < count($this->headScript); $i++){
					$replaceStr .= $this->headScript[$i];
				}
				//$replaceStr .= M3_NL . '//-->' . M3_NL;
				//$replaceStr .= '</script>' . M3_NL;
				$replaceStr .= M3_NL;
				$replaceStr .= '//]]>' . M3_NL;
				$replaceStr .= '</script>' . M3_NL;
			}
			if (count($this->headString) > 0){
				// 任意文字列の場合はそのまま追加
				for ($i = 0; $i < count($this->headString); $i++){
					$replaceStr .= $this->headString[$i];
				}
			}
		}
		return $replaceStr;
	}
	/**
	 * 各部品のHTML出力
	 *
	 * @param string $position			HTMLテンプレート上の書き出し位置
	 * @param string $style				ウィジェットの表示スタイル(空の場合=Joomla!v1.0テンプレート用、空以外=Joomla!v1.5テンプレート用)
	 * @param bool   $isOldJoomla		Joomla!v1.0テンプレート用か出力かどうか
	 * @param array  $attr				その他属性
	 * @return string					出力コンテンツ
	 */
	function getContents($position, $style = '', $isOldJoomla = true, $attr = array())
	{
		static $render;		// Joomla!v1.5テンプレート用
		global $gRequestManager;
		global $gEnvManager;
		
		// ファイル名、ページ名を取得
		$filename	= $gEnvManager->getCurrentPageId();
		$subId		= $gEnvManager->getCurrentPageSubId();
		if (empty($subId)) $subId = $gEnvManager->getDefaultPageSubId();

		// ポジション名表示モードに応じて出力を作成
		$contents = '';		// 出力コンテンツ
		switch ($this->showPositionMode){
			case 0:		// 通常画面
				// ページ定義を取得。同じポジションが続く場合は最初の一度だけ定義を取得
				if (empty($this->pageDefPosition) || $position != $this->pageDefPosition){		// ポジションが異なる場合
					$ret = $this->db->getPageDef($filename, $subId, $position, $rows, 0/*定義セットIdデフォルト*/, true/*表示ウィジェットのみ*/);
					if ($ret){	// 1行以上データが取得できたとき
						$this->pageDefRows = $rows;			// ページ定義レコード
						$this->pageDefPosition = $position;
					} else {
						$this->pageDefRows = array();
						$this->pageDefPosition = '';
					}
				}
				// ウィジェットを実行
				$count = count($this->pageDefRows);
				
				if ($isOldJoomla){			// echo出力のとき(Joomla!v1.0テンプレートの場合)
					ob_start();// バッファ作成

					// ウィジェットヘッダ(Joomla!1.0用)を出力するテンプレートかどうかチェック
					$widgetHeaderType = $this->getTemplateWidgetHeaderType();
					for ($i = 0; $i < $count; $i++){
						$widgetId = $this->pageDefRows[$i]['wd_id'];
						
						// ### 遅延実行ウィジェットはキャッシュしない ###
						// キャッシュデータがあるときはキャッシュデータを使用
						$cacheData = $this->gCache->getWidgetCache($request, $this->pageDefRows[$i], $metaTitle, $metaDesc, $metaKeyword);

						if (empty($cacheData)){		// キャッシュデータがないとき
							ob_clean();
							$ret = $this->pageDefLoop($i, $this->pageDefRows[$i], $style, $titleTag, $widgetHeaderType);
							if (!$ret) break;
							$widgetContent = ob_get_contents();
							
							// キャッシュデータを設定
							$this->gCache->setWidgetCache($gRequestManager, $this->pageDefRows[$i], $widgetContent,
															$this->lastHeadTitle, $this->lastHeadDescription, $this->lastHeadKeywords);
															
							// ウィジェットの外枠タグを設定
							$widgetContent = '<div class="' . self::WIDGET_TAG_HEAD_SHORT . $widgetId . '">' . $widgetContent . '</div>';
							if ($this->isPageEditable){		// 一般画面ページ編集可能モードのとき
								$configId = $this->pageDefRows[$i]['pd_config_id'];		// 定義ID
								$serial = $this->pageDefRows[$i]['pd_serial'];		// シリアル番号
								$hasAdmin = '0';		// 管理画面があるかどうか
								if ($this->pageDefRows[$i]['wd_has_admin']) $hasAdmin = '1';
								$shared = '0';		// 共通属性があるかどうか
								if (empty($this->pageDefRows[$i]['pd_sub_id'])) $shared = '1';	// 共通ウィジェットのとき
								$m3Option = 'm3="widgetid:' . $widgetId . '; serial:' . $serial . '; configid:' . $configId . '; useconfig:' . $hasAdmin . '; shared:' . $shared . '"';
								$widgetContent = '<div class="m3_widget" rel="#m3editwidget" ' . $m3Option . '>' . $widgetContent . '</div>';
							}
						} else {		// キャッシュデータがあるとき
							$widgetContent = $cacheData;
							
							// HTMLのメタタグを設定
							if (!empty($metaTitle)) $this->setHeadSubTitle($metaTitle);
							if (!empty($metaDesc)) $this->setHeadDescription($metaDesc);
							if (!empty($metaKeyword)) $this->setHeadKeywords($metaKeyword);
						}
						$contents .= $widgetContent;
					}
					ob_end_clean();		// バッファ破棄
					
					if ($i < $count) return '';// 処理中断のときは終了
				} else {			// Joomla!v1.5テンプレートの場合
					for ($i = 0; $i < $count; $i++){
						$widgetId = $this->pageDefRows[$i]['wd_id'];
														
						// ### 遅延実行ウィジェットはキャッシュしない ###
						// キャッシュデータがあるときはキャッシュデータを使用
						$cacheData = $this->gCache->getWidgetCache($request, $this->pageDefRows[$i], $metaTitle, $metaDesc, $metaKeyword);
							
						if (empty($cacheData)){		// キャッシュデータがないとき
							// ウィジェットのタイトルを初期化
							$gEnvManager->setCurrentWidgetTitle('');
						
							// Joomla用のパラメータを初期化
							$gEnvManager->setCurrentWidgetJoomlaParam(array());
							
							ob_clean();
							$ret = $this->pageDefLoop($i, $this->pageDefRows[$i], $style, $titleTag, false);
							$widgetContent = ob_get_contents();

							$trimContent = trim($widgetContent);
							if (!empty($trimContent) && !empty($this->pageDefRows[$i]['pd_use_render'])){		// 出力が空でなく、Joomla!の描画処理を使用する場合
								// Joomla!ウィジェットの出力に埋め込む
								if (strcasecmp($style, 'none') != 0){
									// オブジェクト作成
									if (!isset($render)) $render = new JRender();
								
									// デフォルトのウィジェットタイトル取得
									$defaultTitle = $gEnvManager->getCurrentWidgetTitle();
								
									// Joomla用のパラメータを取得
									$joomlaParam = $gEnvManager->getCurrentWidgetJoomlaParam();

									// 遅延ウィジェットのときはタイトルタグを埋め込む
									if (!empty($titleTag)) $defaultTitle = $titleTag;
								
									// タイトルが空でタイトル表示を行う場合は、デフォルトタイトルを使用
									$title = $this->pageDefRows[$i]['pd_title'];
									if ($this->pageDefRows[$i]['pd_title_visible']){		// タイトル表示のとき
										if (empty($title)) $title = $defaultTitle;
									} else {
										$title = '';			// タイトルは非表示
									}
									
									// Joomla用パラメータ作成
									$params = array();				// ウィジェットごとの属性
									$joomlaClass = $this->pageDefRows[$i]['wd_joomla_class'];
									$widgetType = $this->pageDefRows[$i]['wd_type'];		// ウィジェットタイプ
									if (!empty($joomlaClass)) $params['moduleclass_sfx'] = $joomlaClass;
								
									if (strcmp($position, 'main') == 0){// メイン部のとき
										$widgetContent = $render->getComponentContents($style, $widgetContent, $title, $attr, $params);
									} else if (strStartsWith($position, 'user')){// ナビゲーションメニュー位置の場合
										$moduleContent = '';
										if ($style == '_mainmenu'){		// ナビゲーションバータイプ
											$moduleContent = $render->getMenuContents($style, $widgetContent, $title, $attr, $params);
										
											// ナビゲーションバータイプで作成できないときはデフォルトの出力を取得
											if (empty($moduleContent)) $moduleContent = $render->getModuleContents('xhtml', $widgetContent, $title, $attr, $params);
										} else {
											$moduleContent = $render->getModuleContents($style, $widgetContent, $title, $attr, $params);
										}
										$widgetContent = $moduleContent;
									} else {		// その他の位置のとき
										/*$moduleContent = '';
										if ($widgetType == 'menu' && isset($joomlaParam['moduleclass_sfx'])){		// メニュータイプのウィジェットでjoomla用パラメータの設定があるとき
											$params['moduleclass_sfx'] = $joomlaParam['moduleclass_sfx'];
											$moduleContent = $render->getMenuContents($style, $widgetContent, $title, $attr, $params);
										}
										if (empty($moduleContent)) $moduleContent = $render->getModuleContents($style, $widgetContent, $title, $attr, $params);
										$widgetContent = $moduleContent;
										*/
										if (isset($joomlaParam['moduleclass_sfx'])) $params['moduleclass_sfx'] = $joomlaParam['moduleclass_sfx'];// ウィジェットでjoomla用パラメータの設定があるとき
										$widgetContent = $render->getModuleContents($style, $widgetContent, $title, $attr, $params);
									}
								}
	
							}
							if (!$ret) return '';		// 処理中断のときは終了
							
							// キャッシュデータを設定
							$this->gCache->setWidgetCache($gRequestManager, $this->pageDefRows[$i], $widgetContent,
															$this->lastHeadTitle, $this->lastHeadDescription, $this->lastHeadKeywords);
															
							// ウィジェットの外枠タグを設定
							$widgetContent = '<div class="' . self::WIDGET_TAG_HEAD_SHORT . $widgetId . '">' . $widgetContent . '</div>';
							if ($this->isPageEditable){		// 一般画面ページ編集可能モードのとき
								//$editInfo = 'widgetid:' . $this->pageDefRows[$i]['wd_id'];
								$configId = $this->pageDefRows[$i]['pd_config_id'];		// 定義ID
								$serial = $this->pageDefRows[$i]['pd_serial'];		// シリアル番号
								$hasAdmin = '0';		// 管理画面があるかどうか
								if ($this->pageDefRows[$i]['wd_has_admin']) $hasAdmin = '1';
								$shared = '0';		// 共通属性があるかどうか
								if (empty($this->pageDefRows[$i]['pd_sub_id'])) $shared = '1';	// 共通ウィジェットのとき
								$m3Option = 'm3="widgetid:' . $widgetId . '; serial:' . $serial . '; configid:' . $configId . '; useconfig:' . $hasAdmin . '; shared:' . $shared . '"';
								$widgetContent = '<div class="m3_widget" rel="#m3editwidget" ' . $m3Option . '>' . $widgetContent . '</div>';
							}
						} else {		// キャッシュデータがあるとき
							$widgetContent = $cacheData;
							
							// HTMLのメタタグを設定
							if (!empty($metaTitle)) $this->setHeadSubTitle($metaTitle);
							if (!empty($metaDesc)) $this->setHeadDescription($metaDesc);
							if (!empty($metaKeyword)) $this->setHeadKeywords($metaKeyword);
						}
						$contents .= $widgetContent;
					}
				}
			
				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:		// ポジション表示
				$contents .= '<div style="background-color:#eee;margin:2px;padding:10px;border:3px solid #f00;color:#700;">ポジション名: ';
				$contents .= '<b>' . $position . '</b>';
				$contents .= '</div>';
				break;
			case 2:		// ポジション表示(ウィジェット付き)
				$rev = '555';			// データのリビジョン番号
				// ポジションのHTMLタグIDを作成
				$num = 0;
				$posId = '';
				for ($i = 0; $i < 100; $i++){
					$posId = $position . '_' . $num;
					$viewPosId = self::POSITION_TAG_HEAD . $posId;
					if (!in_array($viewPosId, $this->viewPosId)) break;
					$num++;
				}
				$this->viewPosId[] = $viewPosId;// IDを保存
				
				// ページ定義を取得。同じポジションが続く場合は最初の一度だけ定義を取得
				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 = '';
					}
				}
				$contents .= '<div id="' . $viewPosId . '" class="m3_widgetpos_box" m3="pos:' . $position . ';rev:' . $rev . ';">' . M3_NL;		// リビジョン番号を付加
				$contents .= '<h2>' . $position . '</h2>' . M3_NL;
				
				// ウィジェットイメージを表示
				$widgetTagHead = self::WIDGET_TAG_HEAD . $posId;
				$contents .= $this->getWidgetList($gEnvManager->getCurrentPageId(), $gEnvManager->getCurrentPageSubId(), $widgetTagHead, $this->pageDefRows);

				$contents .= '</div>' . M3_NL;
				break;
			default:
				$contents .= '<div style="background-color:#eee;margin:2px;padding:10px;border:1px solid #f00;color:#700;">param error</div>';
				break;
		}
		// ポジションを保存
		$this->viewPositions[] = $position;
		
		return $contents;
	}
	/**
	 * BODYタグに付加するスタイルを取得(管理画面用)
	 *
	 * @param string 		CSS文字列
	 */
	function getBodyStyle()
	{
		// 画面透過モードのときスタイルを追加
		$transCss = '';
		if ($this->isTransparentMode) $transCss = ' style="background-color:transparent;"';
		return $transCss;
	}
	/**
	 * 各部品の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;		// ウィジェットが設定されていないポジション名を表示するために固定で値を返す
		}
		
		// 単一ポジション以外の設定のときは固定で返す(or等)
		$pos = strpos($position, ' ');
		if ($pos !== false) 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, 0/*定義セットIdデフォルト*/, true/*表示ウィジェットのみ*/);
			if ($ret){	// 1行以上データが取得できたとき
				$this->pageDefRows = $rows;			// ページ定義レコード
				$this->pageDefPosition = $position;
			} else {
				$this->pageDefRows = array();
				$this->pageDefPosition = '';
			}
		}
		return count($this->pageDefRows);
	}
	/**
	 * ウィジェット情報取得
	 *
	 * 画面作成機能でウィジェット情報を取得するためのAjaxインターフェイス
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 */
	function getWidgetInfoByAjax($request)
	{
		global $gEnvManager;
		global $gDesignManager;
		global $gCacheManager;
		
		// アクセスするページIDからPC用、携帯用、スマートフォン用かを判断
		$widgetDeviceType = 0;		// 端末タイプをPC用に初期化
		$pageId		= $request->trimValueOf(M3_REQUEST_PARAM_DEF_PAGE_ID);
		$pageSubId	= $request->trimValueOf(M3_REQUEST_PARAM_DEF_PAGE_SUB_ID);
		$mobilePageIdPrefix = M3_DIR_NAME_MOBILE . '_';
		$smartphonePageIdPrefix = M3_DIR_NAME_SMARTPHONE . '_';
		if (strncmp($pageId, $mobilePageIdPrefix, strlen($mobilePageIdPrefix)) == 0){
			$widgetDeviceType = 1;		// 携帯用
		} else if (strncmp($pageId, $smartphonePageIdPrefix, strlen($smartphonePageIdPrefix)) == 0){
			$widgetDeviceType = 2;		// スマートフォン用
		}

		$task = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_TASK);
		if ($task == 'list'){
			// ウィジェット一覧を取得
			$ret = $this->db->getAvailableWidgetList($widgetDeviceType, $rows);
			if ($ret){
				for ($i = 0; $i < count($rows); $i++){
					$widgetId = $rows[$i]['wd_id'];
					$desc = $rows[$i]['wd_description'];
					$widgetTag = self::WIDGET_TYPE_TAG_HEAD . $widgetId;
					$image = $gDesignManager->getWidgetIconUrl($widgetId, self::WIDGET_ICON_IMG_SIZE);
					if ($gEnvManager->getUseSslAdmin()){
						//$image = str_replace('http://', 'https://', $image);		// SSL通信の場合はSSL用に変換
						$image = $gEnvManager->getSslUrl($image);
					}
					$imageTag = '<img class="' . self::WIDTET_CLASS_NAME . '" src="' . $image . '" ';
					$imageTag .= 'width="' . self::WIDGET_ICON_IMG_SIZE . '"';
					$imageTag .= ' height="' . self::WIDGET_ICON_IMG_SIZE . '"';
					$imageTag .= ' />';
					echo '<dl class="m3_widgetlist_item" id="' . $widgetTag . '">' . M3_NL;
					echo '<dt>' . $rows[$i]['wd_name'] . '</dt>' . M3_NL;			// ウィジェット名
					echo '<dd><table width="100%"><tr valign="top"><td width="35">' . $imageTag . '</td><td>' . $desc . '</td></tr></table></dd>' . M3_NL;
					echo '</dl>' . M3_NL;
				}
			}
		} else if ($task == 'wget' || $task == 'wdelete' || $task == 'wtoggle' || $task == 'wadd' || $task == 'wmove'){	// ウィジェット再取得、ウィジェット削除,ウィジェット共通属性変更、ウィジェット追加、ウィジェット移動のとき
			$rev	= $request->trimValueOf('rev');			// リビジョン
			$serial = $request->trimValueOf('serial');
			$position = $request->trimValueOf('pos');
			$widgetsStr = $request->trimValueOf('widgets');
			if (empty($widgetsStr)){
				$widgets = array();
			} else {
				$widgets = explode(',', $widgetsStr);
			}
			$shared = $request->trimValueOf('shared');
			$updatepos = explode(',', $request->trimValueOf('updatepos'));
			$index = $request->trimValueOf('index');
			
			// 処理ごとのパラメータ
			if ($task == 'wmove'){
				$positions = explode(',', $position);
				if (count($positions) >= 2){
					$position = $positions[0];
					$position2 = $positions[1];
				} else {
					$position = $positions[0];
					$position2 = '';
				}
			}
			// ##### エラーチェック #####
			$isErr = false;
			// リビジョンのエラーチェック
			$rev = '111';			// データのリビジョン番号

			// 変更前データ取得
			$ret = $this->db->getPageDef($pageId, $pageSubId, $position, $rows);	// 0レコードでも正常とする
			
			// 変更前のウィジェットのシリアル番号をチェック
			if (count($widgets) == count($rows)){
				if (!($task == 'wmove' && empty($position2))){			// 同一ブロック内の移動の場合はチェックなし
					for ($i = 0; $i < count($rows); $i++){
						if ($widgets[$i] != $rows[$i]['pd_serial']){// シリアル番号
							$isErr = true;
							break;
						}
					}
				}
			} else {
				$isErr = true;
			}

			// データの更新
			if (!$isErr){		// エラーなしのとき
				if ($task == 'wdelete'){
					$ret = $this->db->deleteWidget($serial);
				} else if ($task == 'wtoggle'){
					$newShared = 0;
					if (empty($shared)) $newShared = 1;
					$ret = $this->db->toggleSharedWidget($pageId, $pageSubId, $serial, $newShared);
				} else if ($task == 'wadd'){	// ウィジェットの追加
					$widget = $request->trimValueOf('widget');
					
					// エラーチェック
					if (empty($widget)) $isErr = true;
					
					// ウィジェットを追加
					if (!$isErr) $this->db->addWidget($pageId, $pageSubId, $position, $widget, $index);
				} else if ($task == 'wmove'){
					// ウィジェットを移動
					if (!$isErr) $this->db->moveWidget($pageId, $pageSubId, $position, $serial, $index);
				}
			}
			// 再表示データ取得
			$ret = $this->db->getPageDef($pageId, $pageSubId, $position, $rows);// 0レコードでも正常とする
			
			// 移動のときは、移動元と移動先の再表示データを取得
			if ($task == 'wmove' && !empty($position2)){
				$ret = $this->db->getPageDef($pageId, $pageSubId, $position2, $rows2);// 0レコードでも正常とする
			}

			// 更新データを作成
			// 更新対象のポジションブロック
			echo '<div>' . M3_NL;
			for ($i = 0; $i < count($updatepos); $i++){
				// ウィジェットIDヘッダ作成
				$widgetTagHead = str_replace(self::POSITION_TAG_HEAD, self::WIDGET_TAG_HEAD, $updatepos[$i]);
					
				// ポジション名取得
				$posName = str_replace(self::POSITION_TAG_HEAD, '', substr($updatepos[$i], 0, strlen($updatepos[$i]) - strlen(strrchr($updatepos[$i], "_"))));
				if ($task == 'wmove' && $posName == $position2){
					// ウィジェット一覧外枠
					echo '<div id="' . $updatepos[$i] . '" class="m3_widgetpos_box" m3="pos:' . $position2 . ';rev:' . $rev . ';">' . M3_NL;		// リビジョン番号を付加
					echo '<h2>' . $position2 . '</h2>' . M3_NL;
				
					// ウィジェット一覧出力
					echo $this->getWidgetList($pageId, $pageSubId, $widgetTagHead, $rows2);
				} else {
					// ウィジェット一覧外枠
					echo '<div id="' . $updatepos[$i] . '" class="m3_widgetpos_box" m3="pos:' . $position . ';rev:' . $rev . ';">' . M3_NL;		// リビジョン番号を付加
					echo '<h2>' . $position . '</h2>' . M3_NL;
				
					// ウィジェット一覧出力
					echo $this->getWidgetList($pageId, $pageSubId, $widgetTagHead, $rows);
				}
				// ウィジェット一覧外枠
				echo '</div>' . M3_NL;
			}
			echo '</div>' . M3_NL;
			
			// キャッシュデータをクリア
			$gCacheManager->clearAllCache();
		}
	}
	/**
	 * 画面作成用ウィジェット一覧データ出力
	 *
	 * @param string $pageId			ページID
	 * @param string $pageSubId			ページサブID
	 * @param string $widgetTagHead		HTMLウィジェットID用のヘッダ
	 * @param array $rows				ウィジェット一覧データ
	 * @return string					ウィジェット一覧出力
	 */
	function getWidgetList($pageId, $pageSubId, $widgetTagHead, $rows)
	{
		global $gEnvManager;
		global $gDesignManager;
		
		if ($gEnvManager->getUseSslAdmin()){
			$rootUrl = $gEnvManager->getSslRootUrl();
		} else {
			$rootUrl = $gEnvManager->getRootUrl();
		}

		// ページのコンテンツタイプを取得
		$line = $this->getPageInfo($pageId, $pageSubId);
		if (!empty($line)) $pageContentType = $line['pn_content_type'];
			
		$contents = '';		// ウィジェット一覧出力コンテンツ
		for ($i = 0; $i < count($rows); $i++){
			$widgetId = $rows[$i]['wd_id'];
			$desc = $rows[$i]['wd_description'];
			$widgetIndex = $rows[$i]['pd_index'];		// 表示順
			$configId = $rows[$i]['pd_config_id'];		// 定義ID
			$serial = $rows[$i]['pd_serial'];		// シリアル番号
			$widgetTag = $widgetTagHead . '_' . $i;				// ウィジェット識別用ユニークタグ
			$image = $gDesignManager->getWidgetIconUrl($widgetId, self::WIDGET_ICON_IMG_SIZE);
			if ($gEnvManager->getUseSslAdmin()){
				//$image = str_replace('http://', 'https://', $image);		// SSL通信の場合はSSL用に変換
				$image = $gEnvManager->getSslUrl($image);
			}
			$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($rows[$i]['pd_config_name'])){
				if ($rows[$i]['wd_use_instance_def'] && $configId == 0){		// インスタンス定義が必要で未定義のとき
					$configName = '<span style="color:red;">[未設定]</span>';
				} else {
					$configName = '';
				}
			} else {
				$configName = '[' . $rows[$i]['pd_config_name'] . ']';
			}
			$hasAdmin = '0';		// 管理画面があるかどうか
			$configImg = '';	// 設定アイコンの表示
			
			// ウィジェットの配置位置に問題があるかどうかを表示
			$widgetContentType = $rows[$i]['wd_content_type'];
			if (!empty($widgetContentType) && $widgetContentType != $pageContentType){
				$title = 'ウィジェット配置注意';
				$configImg .= '<img src="' . $rootUrl . self::NOTICE_ICON_FILE . '" alt="' . $title . '" title="' . $title . '" />&nbsp;';
			}
			if ($rows[$i]['wd_has_admin']){
				$hasAdmin = '1';
				$title = 'ウィジェット設定';
				$configImg .= '<a href="javascript:void(0);" onclick="m3ShowConfigWindow(\'' . $widgetId . '\', \'' . $configId . '\', \'' . $serial . '\');return false;" >' .
								'<img src="' . $rootUrl . self::CONFIG_ICON_FILE . '" alt="' . $title . '" title="' . $title . '" /></a>&nbsp;';
			}
			$shared = '0';		// 共通属性があるかどうか
			$sharedClassName = '';
			if (empty($rows[$i]['pd_sub_id'])){
				$shared = '1';	// 共通ウィジェットのとき
				$sharedClassName = 'm3_widget_shared';			// 共通ウィジェットのクラス
			}
			$m3Option = 'm3="widgetid:' . $widgetId . '; serial:' . $serial . '; configid:' . $configId . '; useconfig:' . $hasAdmin . '; shared:' . $shared . '"';
			$contents .= '<dl class="m3_widget_sortable" id="' . $widgetTag . '" ' . $m3Option . ' >' . M3_NL;
			$contents .= '<dt class="m3_widget_with_check_box ' . $sharedClassName . '">' . $rows[$i]['wd_name'] . '</dt>' . M3_NL;
			$contents .= '<dd><table width="100%"><tr valign="top"><td width="35">' . $imageTag . '</td><td>' . $desc . '</td></tr><table>' . M3_NL;
			$contents .= '<table width="100%"><tr><td>' . $configName . '</td><td align="right">' . $configImg . $widgetIndex . '</td></tr></table></dd>' . M3_NL;
			$contents .= '</dl>' . M3_NL;
		}
		return $contents;
	}
	/**
	 * ウィジェット出力を処理
	 *
	 * @param int $index			行番号
	 * @param array $fetchedRow		fetch取得した行
	 * @param string $style			ウィジェットの表示スタイル(空の場合=Joomla!v1.0テンプレート用、空以外=Joomla!v1.5テンプレート用)
	 * @param string $titleTag    	タイトル埋め込み用タグ(遅延ウィジェットの場合のみ作成)
	 * @param int $widgetHeaderType	ウィジェットタイトルを出力方法(0=出力なし、1=Joomla!v1.0PC用出力、2=Joomla!v1.0携帯用出力)
	 * @return bool					処理を継続するかどうか(true=続行、false=中断)
	 */
	function pageDefLoop($index, $fetchedRow, $style, &$titleTag, $widgetHeaderType = 0)
	{
		global $gEnvManager;
		global $gErrorManager;
		global $gDesignManager;

		// ページ作成中断のときは終了
		if ($this->isAbort) return false;
		
		// ウィジェット実行停止中のときは空で返す
		// 管理者、運営者どのレベルで制限をかける?
		if (!$fetchedRow['wd_active']) return true;
		
		// ページ共通属性ありの場合は現在のページが例外ページにないかチェック
		if (empty($fetchedRow['pd_sub_id'])){
			$exceptPageStr = $fetchedRow['pd_except_sub_id'];
			if (!empty($exceptPageStr)){
				$exceptPageArray = explode(',', $exceptPageStr);
				if (in_array($gEnvManager->getCurrentPageSubId(), $exceptPageArray)) return true;		// 例外ページの場合は出力しない
			}
		}
		
		// ウィジェット表示タイプによる表示制御。システム管理者以上の場合は常時表示。
		if (!$gEnvManager->isSystemAdmin() && $fetchedRow['pd_view_control_type'] != 0){
			switch ($fetchedRow['pd_view_control_type']){
				case 1:			// ログイン時のみ表示
					if (!$gEnvManager->isCurrentUserLogined()) return true;		// ログインしていなければ終了
					break;
				case 2:			// 非ログイン時のみ表示
					if ($gEnvManager->isCurrentUserLogined()) return true;		// ログインしていれば終了
					break;
				default:
					break;
			}
		}
		
		// パラメータ初期化
		$titleTag = '';
		
		// ウィジェット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'];		// サフィックス文字列
		$title = $fetchedRow['wd_name'];		// デフォルトのウィジェットタイトル
		if (empty($title)) $title = $fetchedRow['wd_id'];
		$serial = $fetchedRow['pd_serial'];		// シリアル番号
		$cssStyle	= $fetchedRow['pd_style'];		// CSS
		$lateLaunchIndex = $fetchedRow['wd_launch_index'];		// 遅延実行インデックス
		$shared = false;
		if (empty($fetchedRow['pd_sub_id'])) $shared = true;// 共通属性あり
		if ($this->nonSharedWidgetCount == -1) $this->nonSharedWidgetCount = 0;		// 初期化されていない場合は初期化
		if (!$shared) $this->nonSharedWidgetCount++;	// 非共通ウィジェットの数を更新
		
		// ウィジェットが遅延実行に指定されている場合は、ウィジェットのタグのみ埋め込む
		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, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $tmp6, $tmp7) = $this->latelaunchWidgetParam[$i];
				if ($wId == $widgetId) $maxNo = $index + 1;
			}
			// Joomla!1.0テンプレートの場合はタイトルを修正
			if ($widgetHeaderType > 0 && empty($style)){			// Joomla!1.0テンプレートのとき
				if (!empty($fetchedRow['pd_title'])) $title = $fetchedRow['pd_title'];
			}
			$this->latelaunchWidgetParam[] = array($widgetId, $maxNo, $configId, $prefix, $serial, $style, $cssStyle, $title, $shared);
			
			// 遅延実行用タグを埋め込む
			echo self::WIDGET_ID_TAG_START . $widgetId . self::WIDGET_ID_SEPARATOR . $maxNo . self::WIDGET_ID_TAG_END;
			
			// タイトル用タグ作成
			$titleTag = self::WIDGET_ID_TITLE_TAG_START . $widgetId . self::WIDGET_ID_SEPARATOR . $maxNo . self::WIDGET_ID_TITLE_TAG_END;
		} else {
			// ウィジェットが存在する場合は実行
			if (!file_exists($widgetIndexFile)) {
				echo 'widget not found error: ' . $widgetId;
			} else {
				// パラメータ初期化
				$this->lastHeadCss = '';			// 最後に設定したHTMLヘッダにCSS出力する文字列
				$this->lastHeadScript = '';			// 最後に設定したHTMLヘッダにJavascript出力する文字列
				$this->lastHeadString = '';			// 最後に設定したHTMLヘッダに出力する任意文字列
				$this->lastHeadTitle = '';			// ヘッダ部titleにセットした文字列
				$this->lastHeadDescription = '';	// ヘッダ部descriptionにセットした文字列
				$this->lastHeadKeywords = '';		// ヘッダ部keywordsにセットした文字列
			
				// Joomla!1.0テンプレートのときはウィジェットタイトルを出力
				$joomlaTitleVisble = false;
				if ($widgetHeaderType > 0 && empty($style)){			// Joomla!1.0テンプレートのとき
					if ($fetchedRow['pd_title_visible']){
						if ($widgetHeaderType == 1){		// PC用出力のとき
							$joomlaTitle = $fetchedRow['pd_title'];
							if (empty($joomlaTitle)) $joomlaTitle = $title;
							echo '<table ' . self::JOOMLA10_DEFAULT_WIDGET_MENU_PARAM . '>' . M3_NL;
							echo '<tr><th>' . $joomlaTitle . '</th></tr>' . M3_NL;
							echo '<tr><td>' . M3_NL;
							$joomlaTitleVisble = true;
						} else if ($widgetHeaderType == 2){		// 携帯用出力のとき
							$joomlaTitle = $fetchedRow['pd_title'];
							if (empty($joomlaTitle)) $joomlaTitle = $title;
							echo '<div>' . $joomlaTitle . '</div>' . M3_NL;
							$joomlaTitleVisble = true;
						}
					}
				}
				// ウィジェットの外枠タグを設定
				//echo '<div class="' . self::WIDGET_TAG_HEAD_SHORT . $widgetId . '">' . M3_NL;
				// ウィジェット親のCSS定義があるときは、タグを追加
				if (!empty($cssStyle)) echo '<div style="' . $cssStyle . '">' . M3_NL;
					
				// ウィジェットの前出力
				echo $gDesignManager->getAdditionalWidgetOutput(true);
				
				// 作業中のウィジェットIDを設定
				$gEnvManager->setCurrentWidgetId($widgetId);
	
				// ウィジェット定義IDを設定
				$gEnvManager->setCurrentWidgetConfigId($configId);
			
				// ページ定義のシリアル番号を設定
				$gEnvManager->setCurrentPageDefSerial($fetchedRow['pd_serial']);
					
				// パラメータを設定
				$gEnvManager->setCurrentWidgetPrefix($prefix);		// プレフィックス文字列
			
				// ウィジェットのタイトルを設定
				$gEnvManager->setCurrentWidgetTitle($title);
				
				// ウィジェットのページ共通状況を設定
				$gEnvManager->setIsCurrentWidgetShared($shared);
					
				// 実行ログを残す
				$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('');				// プレフィックス文字列

				// ウィジェットのページ共通状況を解除
				$gEnvManager->setIsCurrentWidgetShared(false);
				
				// ウィジェットの後出力
				echo $gDesignManager->getAdditionalWidgetOutput(false);
//				echo "<!-- ".time()." -->";

				// ウィジェット親のCSS定義があるときは、タグを追加
				if (!empty($cssStyle)) echo '</div>' . M3_NL;
				// ウィジェットの外枠タグを設定
				//echo '</div>' . M3_NL;
				
				// Joomla!1.0テンプレートのときはタイトルを出力
				if ($joomlaTitleVisble && $widgetHeaderType == 1){		// PC用出力のとき
					echo '</td></tr>' . M3_NL;
					echo '</table>' . M3_NL;
				}
			}
		}
		return true;		// 処理継続
	}
	/**
	 * 定義IDを指定してウィジェットの出力を取得
	 *
	 * @param string $widgetId		ウィジェットID
	 * @param int $configId			ウィジェット定義ID
	 * @return string				ウィジェットの出力
	 */
	function getWidgetOutput($widgetId, $configId)
	{
		global $gEnvManager;
		global $gErrorManager;

		// ウィジェットのアクセス権をチェック
		if (!$this->db->canAccessWidget($widgetId)) return '';

		// ウィジェット情報取得
		if (!$this->db->getWidgetInfo($widgetId, $row)) return '';

		// 端末タイプをチェック
		if (intval($row['wd_device_type']) != intval($gEnvManager->getCurrentPageDeviceType())) return '';
		
		// 必要なJavascriptライブラリを追加
		$scritLib = trim($row['wd_add_script_lib']);
		if (!empty($scritLib)) $this->addScript('', $scritLib);
		
		// バッファ作成
		ob_start();

		// ウィジェット実行ファイル取得
		$widgetIndexFile = $gEnvManager->getWidgetsPath() . '/' . $widgetId . '/index.php';
					
		// 作業中のウィジェットIDを設定
		$saveWidgetId = $gEnvManager->getCurrentWidgetId();
		$gEnvManager->setCurrentWidgetId($widgetId);

		// ウィジェット定義IDを設定
		$saveConfigId = $gEnvManager->getCurrentWidgetConfigId();
		$gEnvManager->setCurrentWidgetConfigId($configId);
	
		// ページ定義のシリアル番号を設定
		//$gEnvManager->setCurrentPageDefSerial(0);		// 未使用?
			
		// パラメータを設定
		//$gEnvManager->setCurrentWidgetPrefix($prefix);		// プレフィックス文字列
	
		// ウィジェットのタイトルを設定
		//$gEnvManager->setCurrentWidgetTitle($title);
		
		// ウィジェットのページ共通状況を設定
		//$gEnvManager->setIsCurrentWidgetShared($shared);
			
		// 実行ログを残す
		$this->db->writeWidgetLog($widgetId, 0/*ページ実行*/);
		
		// ウィジェットを実行
		//require_once($widgetIndexFile);
		// ウィジェットの呼び出しは、複数回存在する可能性があるのでrequire_once()で呼び出さない
		$msg = 'widget-start(' . $widgetId . ')';
		$gErrorManager->writeDebug(__METHOD__, $msg);		// 時間計測用
		if (file_exists($widgetIndexFile)){
			require($widgetIndexFile);
		} else {
			echo 'widget not found error: ' . $widgetId;
		}
		$msg = 'widget-end(' . $widgetId . ')';
		$gErrorManager->writeDebug(__METHOD__, $msg);		// 時間計測用

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

		// ウィジェットのページ共通状況を解除
		//$gEnvManager->setIsCurrentWidgetShared(false);

		// 現在のバッファ内容を取得し、バッファを破棄
		$output = ob_get_contents();
		ob_end_clean();
					
		return $output;
	}
	/**
	 * インナーウィジェットの操作
	 *
	 * @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;
		
		// ウィジェットIDとインナーウィジェットIDを取り出す
		list($widgetId, $iWidgetId) = explode(M3_WIDGET_ID_SEPARATOR, $id);

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

		// 結果を取得
		if ($this->gInstance->getCmdParamManager()->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;
	}
	/**
	 * ファイルダウンロード
	 *
	 * @param string $filePath			ダウンロードするファイルのファイルパス
	 * @param string $downloadFilename	ダウンロード時のファイル名
	 * @param bool   $deleteFile		実行後ファイルを削除するかどうか(成功失敗に関係なく)
	 * @return bool						true=成功、false=失敗
	 */
	function downloadFile($filePath, $downloadFilename, $deleteFile=false)
	{
		// ファイルサイズ取得
		$fileSize = filesize($filePath);
		
		// バッファ内容が残っているときは破棄
		if (ob_get_level() > 0) ob_end_clean();
		
		header('Cache-Control: public');		// IE6+SSHでダウンロードエラーが出る問題を回避
		header('Pragma: public');				// IE6+SSHでダウンロードエラーが出る問題を回避
	    header('Content-Disposition: attachment; filename=' . $downloadFilename);
		header('Content-Length: ' . $fileSize);
	    header('Content-Type: application/octet-stream; name=' . $downloadFilename);
	    $fp = fopen($filePath, "r");
	    echo fread($fp, $fileSize);
	    fclose($fp);
		
		ob_end_flush();
		
		// ファイル削除
		if ($deleteFile) unlink($filePath);
		return true;
	}
	/**
	 * 指定URLへリダイレクト
	 *
	 * @param string $url			遷移先URL。未指定の場合は現在のスクリプト。URLでないときは、現在のスクリプトに付加。
	 * @param bool $noMessage		画面を遷移させたとき、ドコモ携帯端末でダイアログ(サイトが移動しました(301))が出ないようにするオプション
	 * @return 						なし
	 */
	function redirect($url = '', $noMessage = false)
	{
		global $gEnvManager;

		// すでにリダイレクトが設定されている場合は終了
		if ($this->isRedirect) return;				// リダイレクトするかどうか
		
		$toUrl = $url;
		if (empty($toUrl)){
			$toUrl = $gEnvManager->getCurrentScriptUrl();
		} else if (strncmp($toUrl, 'http://', 7) != 0 && strncmp($toUrl, 'https://', 8) != 0){	// URL以外のときはクエリー文字列と判断する
			$toUrl = $gEnvManager->getCurrentScriptUrl() . $toUrl;
		}

		// SSL化が必要な場合はhttpsに変更
		$isSslPage = false;
		if ($gEnvManager->isAdminUrlAccess($toUrl)){		// 管理画面へのアクセスのとき
			// 管理画面のSSL状態を参照
			if ($gEnvManager->getUseSslAdmin()) $isSslPage = true;		// 管理画面でSSLを使用するとき
		} else {
			// ファイル名を取得
			$paramArray = array();
			//list($filename, $query) = explode('?', basename($toUrl));
			list($url, $query) = explode('?', $toUrl);
			$baseUrl = dirname($url);
			$filename = basename($url);
			if (empty($filename)) $filename = M3_FILENAME_INDEX;
			if (!empty($query)) parse_str($query, $paramArray);		// クエリーの解析
		
			// ページIDを取得
			$pageId = basename($filename, '.php');
			$pageSubId = $paramArray[M3_REQUEST_PARAM_PAGE_SUB_ID];
			
			// ページのSSL設定状況を取得
			$isSslPage = $this->isSslPage($pageId, $pageSubId);
			
			// 階層化ページの場合はURLを修正
			if ($this->gSystem->hierarchicalPage() && $filename == M3_FILENAME_INDEX){
				$toUrl = $baseUrl . '/' . $pageSubId . '/';
				unset($paramArray[M3_REQUEST_PARAM_PAGE_SUB_ID]);
					
				$paramStr = $this->_createUrlParamStr($paramArray);
				if (!empty($paramStr)) $toUrl .= '?' . $paramStr;
			}
		}
		if ($isSslPage){
			//$toUrl = str_replace('http://', 'https://', $toUrl);
			$toUrl = $gEnvManager->getSslUrl($toUrl);		// SSL用URLに変換
		} else {
			$toUrl = str_replace('https://', 'http://', $toUrl);
		}

		// バッファ内容が残っているときは破棄
		if (ob_get_level() > 0) ob_end_clean();

		if ($noMessage){
			header('HTTP/1.1 302 Found(Moved Temporary)');		// ダイアログメッセージを抑止(ドコモ携帯端末用)
		} else {
			header('HTTP/1.1 301 Moved Permanently');
		} 
		header('Location: ' . $toUrl);
		
		$this->isRedirect = true;				// リダイレクトするかどうか
//		exit();
	}
	/**
	 * リダイレクト処理かどうかを返す
	 *
	 * @return bool		true=リダイレクト、false=リダイレクトでない
	 */
	function isRedirect()
	{
		return $this->isRedirect;
	}
	/**
	 * 指定URLのディレクトリへリダイレクト
	 *
	 * @return 						なし
	 */
	function redirectToDirectory()
	{
		global $gEnvManager;

		// ファイル名を削除
		$dirPath = dirname($gEnvManager->getCurrentScriptUrl()) . '/';
		$this->redirect($dirPath);
	}
	/**
	 * インストール用URLへリダイレクト
	 *
	 * @return 						なし
	 */
	function redirectToInstall()
	{
		global $gEnvManager;
		
		$sytemRootUrl = $gEnvManager->calcSystemRootUrl();
		$this->redirect($sytemRootUrl . '/admin/install.php');
	}
	/**
	 * ログイン、ログアウト処理を行った後、リダイレクト
	 *
	 * @param RequestManager	$request		HTTPリクエスト処理クラス
	 * @param bool				$success		ログインの成否
	 * @param string			$redirectUrl	ログイン成功の場合のリダイレクト先
	 * @return int								0=何も処理しなかった場合、1=ログイン処理、2=ログアウト処理
	 */
	function standardLoginLogoutRedirect($request, &$success, $redirectUrl = '')
	{
		global $gEnvManager;
		global $gAccessManager;
		global $gRequestManager;
		
		// ログイン、ログアウト処理、および、コンテナの起動
		$cmd = $request->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
		if ($cmd == M3_REQUEST_CMD_LOGIN){			// ログインの場合
			// ユーザ認証
			if ($gAccessManager->userLogin($request) == true){
				// リダイレクト処理
				$this->redirect($redirectUrl);
				$success = true;		// ログイン成功
			} else {	// ログイン失敗のとき
				$success = false;		// ログイン失敗
			}
			return 1;
		} else if ($cmd == M3_REQUEST_CMD_LOGOUT){		// ログアウト
			// ログアウト処理
			$gAccessManager->userLogout(true);
			
			// リダイレクト処理
			$this->redirect($redirectUrl);
			return 2;
		} else {
			return 0;
		}
	}
	/**
	 * ウィジェットがセットされているページサブIDを取得
	 *
	 * @param string $pageId		ページID
	 * @param string $widgetId		対象ウィジェットID
	 * @param int $configId			ウィジェット定義ID
	 * @return string				ページサブID
	 */
	function getPageSubIdByWidget($pageId, $widgetId, $configId = 0)
	{
		$pageSubId = '';
		
		// 対象のウィジェットのページサブIDを取得
		$ret = $this->db->getSubPageId($widgetId, $pageId, $rows);
		if ($ret){// データが存在する
			for ($i = 0; $i < count($rows); $i++){
				if (!empty($rows[$i]['pd_sub_id']) && $rows[$i]['pd_config_id'] == $configId){
					$pageSubId = $rows[$i]['pd_sub_id'];
					break;
				}
			}
		}
		return $pageSubId;
	}
	/**
	 * 指定のウィジェットがページ上にあるかを取得
	 *
	 * @param string $pageId		ページID
	 * @param string $widgetId		対象ウィジェットID
	 * @param bool $activePageOnly	公開中のページのウィジェットに制限するかどうか。falseの場合はすべてのページのウィジェットを対象とする。
	 * @return bool					true=ページ上にあり、false=ページ上になし
	 */
	function isWidgetOnPage($pageId, $widgetId, $activePageOnly=true)
	{
		$ret = $this->db->isWidgetOnPage($pageId, $widgetId, $activePageOnly, 0/*定義セットID*/);
		return $ret;
	}
	/**
	 * URLで示されるページ上のウィジェットをウィジェット種別で取得
	 *
	 * @param string $url			URL
	 * @param string $widgetType	対象ウィジェットタイプ
	 * @return string				ウィジェットID
	 */
	function getWidgetIdByWidgetType($url, $widgetType)
	{
		$ret = $this->getPageIdFromUrl($url, $pageId, $pageSubId, $param);
		
		// ウィジェットIDを取得
		if ($ret) $widgetId = $this->db->getWidgetIdByType($pageId, $pageSubId, $widgetType);
		return $widgetId;
	}
	/**
	 * URLを解析して、ページID,サブページIDを取得
	 *
	 * @param string $url			URL
	 * @param string $pageId		ページID
	 * @param string $pageSubId		ページサブID
	 * @param array  $urlParam		URLパラメータ
	 * @return bool					true=成功、false=失敗
	 */
	function getPageIdFromUrl($url, &$pageId, &$pageSubId, &$urlParam)
	{
		global $gEnvManager;
			
		// ページID、ページサブIDを求める
		list($page, $other) = explode('?', str_replace($gEnvManager->getRootUrl(), '', $url));
		parse_str($other, $urlParam);
		
		$pageId = str_replace('/', '_', trim($page, '/'));
		$pageId = basename($pageId, '.php');

		// ページサブIDを取得
		$pageSubId = $param[M3_REQUEST_PARAM_PAGE_SUB_ID];
		if (empty($pageSubId)) $pageSubId = $gEnvManager->getDefaultPageSubId();
		return true;
	}
	/**
	 * ウィジェットが組み込まれているページの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 = M3_REQUEST_PARAM_PAGE_SUB_ID . '=' . $subPageId;
		
		$url = $gEnvManager->getDefaultUrl();
		if (!empty($sub)) $url .= '?' . $sub;
		if (!empty($param)) $url .= '&' . $param;
		return $url;
	}
	/**
	 * ウィジェット指定呼び出し用のURLを生成
	 *
	 * @param string $toWidgetId	送信先ウィジェットID
	 * @param string $fromWidgetId	送信元ウィジェットID
	 * @param string $todo			実行パラメータ
	 * @param string $pageId		ページID(空のときは現在のURL)
	 * @return string				生成したURL
	 */
	function createWidgetCmdUrl($toWidgetId, $fromWidgetId, $todo, $pageId = '')
	{
		global $gEnvManager;
		
		$url = $gEnvManager->createPageUrl($pageId);
		
		$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;
	}
	/**
	 * RSS配信用のURLを生成
	 *
	 * @param string $widgetId		実行ウィジェットID
	 * @param string $optionParam	追加パラメータ
	 * @param string $pageId		ページID(空のときは現在のURL)
	 * @param string $pageSubId		ページサブID
	 * @return string				生成したURL
	 */
	function createRssCmdUrl($widgetId, $optionParam = '', $pageId = '', $pageSubId = '')
	{
		global $gEnvManager;
		
		// 現在のページURLを取得
		$url = $gEnvManager->createPageUrl() . '?';
		
		// ページサブIDを取得
		if (empty($pageSubId)) $pageSubId = $this->gEnv->getCurrentWidgetPageSubId();	// ページ共通属性ありのときは空
		if (!empty($pageSubId)) $url .= M3_REQUEST_PARAM_PAGE_SUB_ID . '=' . $pageSubId . '&';
		
		$url .= M3_REQUEST_PARAM_OPERATION_COMMAND . '=' . M3_REQUEST_CMD_RSS;
		$url .= '&' . M3_REQUEST_PARAM_WIDGET_ID . '=' . $widgetId;
		if (!empty($optionParam)) $url .= '&' . $optionParam;
		return $url;
	}
	/**
	 * ウィジェット実行用のURLを生成
	 *
	 * @param string $widgetId	実行ウィジェットID
	 * @param string $optionParam	追加パラメータ
	 * @param string $pageId		ページID(空のときは現在のURL)
	 * @param string $pageSubId		ページサブID
	 * @return string				生成したURL
	 */
	function createDirectWidgetCmdUrl($widgetId, $optionParam = '', $pageId = '', $pageSubId = '')
	{
		global $gEnvManager;
		
		// 現在のページURLを取得
		$url = $gEnvManager->createPageUrl() . '?';
		
		// ページサブIDを取得
		if (empty($pageSubId)) $pageSubId = $this->gEnv->getCurrentWidgetPageSubId();	// ページ共通属性ありのときは空
		if (!empty($pageSubId)) $url .= M3_REQUEST_PARAM_PAGE_SUB_ID . '=' . $pageSubId . '&';
		
		$url .= M3_REQUEST_PARAM_OPERATION_COMMAND . '=' . M3_REQUEST_CMD_DO_WIDGET;
		$url .= '&' . M3_REQUEST_PARAM_WIDGET_ID . '=' . $widgetId;
		if (!empty($optionParam)) $url .= '&' . $optionParam;
		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();
		$ret = $this->db->canAccessPage($pageId, $pageSubId, $pageVisible, $pageSubVisible);
		if ($ret){		// アクセス可能なときは、ユーザ制限もチェックする
			// ページが表示可能かチェック
			if (!$pageVisible || !$pageSubVisible) return false;
			
			if (!$gEnvManager->isCurrentUserLogined() && $this->isUserLimitedPage($pageId, $pageSubId)){			// ユーザがログインされていない状態でユーザ制限されていればアクセス不可
				return false;
			} else {
				return true;
			}
		}
		return false;
	}
	/**
	 * ウィジェットヘッダ(Joomla!1.0用)を出力タイプを取得
	 *
	 * @return int				0=出力しない、1=Joomla!1.0テンプレートPC用、2=Joomla!1.0テンプレート携帯用
	 */	
	function getTemplateWidgetHeaderType()
	{
		global $gEnvManager;
		
		$templateId = $gEnvManager->getCurrentTemplateId();
		if ($templateId == self::ADMIN_TEMPLATE ||		// PC管理用テンプレート
			$templateId == self::M_ADMIN_TEMPLATE){		// 携帯管理用テンプレート
			return 0;
		} else if(strncmp($templateId, 'm/', 2) == 0){		// 携帯用テンプレート
			return 2;		// 携帯テンプレート用出力
		} else {
			return 1;		// PCテンプレート用出力
		}
	}
	/**
	 * SSLが必要なページかどうかを判断
	 *
	 * @param string $pageId	ページID
	 * @param string $pageSubId	ページサブID
	 * @return bool				true=必要、false=不要
	 */	
	function isSslPage($pageId, $pageSubId)
	{
		global $gEnvManager;
		
		// パラメータ修正
		if (empty($pageId)) $pageId = $gEnvManager->getDefaultPageId();
		
		// 管理用ページの場合
		if ($pageId == $gEnvManager->getDefaultAdminPageId()){
			if ($gEnvManager->getUseSslAdmin()){		// 管理用ページにSSLを使用するかどうか
				return true;
			} else {
				return false;
			}
		} else {		// その他のページのとき
			// 一般用ページにSSLを使用しない場合は不要を返す
			if (!$gEnvManager->getUseSsl()) return false;
		}
		
		// 一般用ページでSSLを使用する場合は、データベースの設定をチェックする
		$line = $this->getPageInfo($pageId, $pageSubId);
		if (!empty($line)){
			if ($line['pn_use_ssl']){
				return true;
			} else {
				return false;
			}
		}
		return false;
	}
	/**
	 * ユーザ制限が必要なページかどうかを判断
	 *
	 * @param string $pageId	ページID
	 * @param string $pageSubId	ページサブID
	 * @return bool				true=必要、false=不要
	 */	
	function isUserLimitedPage($pageId, $pageSubId)
	{
		global $gEnvManager;
		
		// パラメータ修正
		if (empty($pageId)) $pageId = $gEnvManager->getDefaultPageId();
		
		$line = $this->getPageInfo($pageId, $pageSubId);
		if (!empty($line)){
			if ($line['pn_user_limited']){
				return true;
			} else {
				return false;
			}
		}
		return false;
	}
	/**
	 * ページ情報を取得
	 *
	 * @param string $pageId	ページID
	 * @param string $pageSubId	ページサブID
	 * @return array			ページ情報レコード
	 */	
	function getPageInfo($pageId, $pageSubId)
	{
		// ページ情報が空のときはデータをロード
		if (empty($this->pageInfo)){
			$records = $this->db->getPageInfoRecords();
			$count = count($records);
			$this->pageInfo = array();
			for ($i = 0; $i < $count; $i++){
				$pId = $records[$i]['pn_id'] . self::PAGE_ID_SEPARATOR . $records[$i]['pn_sub_id'];
				$this->pageInfo[$pId] = $records[$i];
			}
		}
		return $this->pageInfo[$pageId . self::PAGE_ID_SEPARATOR . $pageSubId];
	}
	/**
	 * 現在のページ情報からテンプレートIDを取得
	 *
	 * @return string		テンプレートID
	 */	
	function getTemplateIdFromCurrentPageInfo()
	{
		$templateId = '';
		if (!empty($this->currentPageInfo)) $templateId = $this->currentPageInfo['pn_template_id'];
		return $templateId;
	}
	/**
	 * JavascriptライブラリのIDを取得
	 *
	 * @param int $type			種別(0=すべて、1=jQuery関係すべて、2=jQueryプラグインのみ)
	 * @return array			JavascriptライブラリのID
	 */	
	function getScriptLibId($type = 0)
	{
		// Javascriptライブラリのすべてのキーを取得
		$keys = array_keys($this->libFiles);
		
		$destKeys = array();
		for ($i = 0; $i < count($keys); $i++){
			switch ($type){
				case 1:		// jQuery関係すべて
					if (strStartsWith($keys[$i], 'jquery')) $destKeys[] = $keys[$i];
					break;
				case 2:		// jQueryプラグインのみ
					if (strStartsWith($keys[$i], 'jquery.')) $destKeys[] = $keys[$i];
					break;
			}
		}
		return $destKeys;
	}
	/**
	 * Javascriptライブラリの情報を取得
	 *
	 * @param string $id		ライブラリID
	 * @return array			ライブラリの情報
	 */	
	function getScriptLibInfo($id)
	{
		$libInfo = $this->libFiles[$id];
		if (isset($libInfo)){
			return $libInfo;
		} else {
			return array();
		}
	}
	/**
	 * 管理画面用jQueryUIテーマを取得
	 *
	 * @return string			テーマURL
	 */	
	function getAdminDefaultTheme()
	{
		$themeFile = $this->gEnv->getRootUrl() . self::DEFAULT_THEME_DIR . $this->gSystem->adminDefaultTheme() . '/'. self::THEME_CSS_FILE;
		return $themeFile;
	}
	/**
	 * URLパラメータ文字列作成
	 *
	 * @param array $paramArray			URL作成用のパス
	 * @return string					作成したURLパラメータ
	 */
	function _createUrlParamStr($paramArray)
	{
		$destParam = '';
		if (count($paramArray) == 0) return $destParam;

		$sortParam = array();
		$keys = array_keys($paramArray);
		$keyCount = count($keys);
		for ($i = 0; $i < $keyCount; $i++){
			$key = $keys[$i];
			$value = $paramArray[$key];
			$orderNo = $this->urlParamOrder[$key];
			if (!isset($orderNo)) $orderNo = 100;
			$sortParam[] = array('key' => $key, 'value' => $value, 'no' => $orderNo);
		}
		usort($sortParam, create_function('$a,$b', 'return $a["no"] - $b["no"];'));
		
		// 文字列を作成
		$sortCount = count($sortParam);
		for ($i = 0; $i < $sortCount; $i++){
			if ($i > 0) $destParam .= '&';
			$destParam .= rawurlencode($sortParam[$i]['key']) . '=' . rawurlencode($sortParam[$i]['value']);
		}
		return $destParam;
	}
}
?>
