<?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-2010 Magic3 Project.
 * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
 * @version    SVN: $Id: baseWidgetContainer.php 3170 2010-05-29 13:25:55Z fishbone $
 * @link       http://www.magic3.org
 */
// テンプレートライブラリ読み込み
require_once($gEnvManager->getLibPath() . '/patTemplate/patTemplate.php');
require_once($gEnvManager->getLibPath() . '/patTemplate/patError.php');
require_once($gEnvManager->getLibPath() . '/patTemplate/patErrorManager.php');
require_once($gEnvManager->getCommonPath() . '/core.php');
require_once($gEnvManager->getCommonPath() . '/htmlEdit.php');

class BaseWidgetContainer extends Core
{
	protected $_db;	// DB接続オブジェクト
	protected $tmpl;		// テンプレートオブジェクト
	protected $parseCancel;			// テンプレート変換処理を中断するかどうか
	protected $displayMessage = true;		// メッセージを出力するかどうか
	protected $messageAttr;					// メッセージ用の追加属性
	protected $errorMessage    = array();		// アプリケーションのエラー
	protected $warningMessage  = array();		// ユーザ操作の誤り
	protected $guidanceMessage = array();		// ガイダンス
	protected $optionUrlParam = array();		// URLに付加する値
	protected $_defConfigId;					// ページ定義のウィジェット定義ID
	protected $_defSerial;						// ページ定義のレコードシリアル番号
	protected $urlParamOrder;					// URLパラメータの並び順
	const PASSWORD_LENGTH = 8;		// パスワード長
	const HELP_HEAD = '_help_';		// ヘルプ埋め込み用タグのヘッダ部
		
	// メッセージの種別
	const MSG_APP_ERR  = 1;		// アプリケーションエラー
	const MSG_USER_ERR = 2;		// ユーザ操作エラー
	const MSG_GUIDANCE = 3;		// ガイダンス
	
	/**
	 * コンストラクタ
	 */
	function __construct()
	{
		// 親クラスを呼び出す
		parent::__construct();
		
		// DBオブジェクト取得
		$this->_db = $this->gInstance->getSytemDbObject();
		
		// URLパラメータ並び順
		$this->urlParamOrder = array(
			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_PAGE_NO      			=> 13,		// ページ番号
			M3_REQUEST_PARAM_LIST_NO				=> 14,		// 一覧番号
			M3_REQUEST_PARAM_ITEM_NO	      		=> 15,		// 項目番号
			M3_REQUEST_PARAM_OPERATION_TODO			=> 16,		// 指定ウィジェットに実行させる処理
			M3_REQUEST_PARAM_FROM					=> 17,		// メッセージの送信元ウィジェットID
			M3_REQUEST_PARAM_VIEW_STYLE				=> 18,		// 表示スタイル
			M3_REQUEST_PARAM_FORWARD				=> 19,		// 画面遷移用パラメータ
			M3_REQUEST_PARAM_ADMIN_KEY				=> 20,		// 管理者一時キー
			M3_REQUEST_PARAM_OPEN_BY				=> 21,		// ウィンドウの開き方
			M3_REQUEST_PARAM_DEF_PAGE_ID			=> 22,		// ページID(画面編集用)
			M3_REQUEST_PARAM_DEF_PAGE_SUB_ID		=> 23,		// ページサブID(画面編集用)
			M3_REQUEST_PARAM_PAGE_DEF_SERIAL		=> 24,		// ページ定義のレコードシリアル番号(設定画面起動時)
			M3_REQUEST_PARAM_PAGE_DEF_CONFIG_ID		=> 25,		// ページ定義のウィジェット定義ID(設定画面起動時)
			M3_REQUEST_PARAM_CONTENT_ID				=> 26,		// コンテンツID
			M3_REQUEST_PARAM_CONTENT_ID_SHORT		=> 27);				// コンテンツID(略式)
	}
	/**
	 * 起動マネージャから呼ばれる唯一のメソッド
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @return								なし
	 */
	function process($request)
	{
		// 管理画面へのアクセスかどうか
		$isAdminDirAccess = $this->gEnv->isAdminDirAccess();
			
		// ウィジェット単位のアクセス制御
		if (method_exists($this, '_checkAccess')){
			// アクセス不可のときはここで終了
			if (!$this->_checkAccess($request)) return;
		}
					
		// ディスパッチ処理
		if (method_exists($this, '_dispatch')){
			// 処理を継続しない場合は終了
			if (!$this->_dispatch($request, $param)) return;
		}
		if (method_exists($this, '_setTemplate')){
			// テンプレートファイル名を取得
			// $paramは、任意使用パラメータ
			$templateFile = $this->_setTemplate($request, $param);
			
			// テンプレートファイル名が空文字列のときは、テンプレートライブラリを使用しない
			if ($templateFile != ''){
				// テンプレートオブジェクト作成
				$this->__setTemplate();
				
				// テンプレートファイルを設定
				$this->tmpl->readTemplatesFromFile($templateFile);

				// エラーメッセージ組み込み
				$this->__assign();
			}
			// 各ウィジェットごとのテンプレート処理、テンプレートを使用しないときは出力処理(Ajax等)
			if (method_exists($this, '_preAssign')) $this->_preAssign($request, $param);
			
			// 各ウィジェットごとのテンプレート処理、テンプレートを使用しないときは出力処理(Ajax等)
			if (method_exists($this, '_assign')){
				// 管理画面へのアクセスの場合は管理用POST値を設定
				if ($isAdminDirAccess){
					// ウィジェット定義IDとページ定義のレコードシリアル番号をURLから取得
					$this->_defConfigId = $this->getPageDefConfigId($request);	// ページ定義のウィジェット定義ID
					$this->_defSerial = $this->getPageDefSerial($request);		// ページ定義のレコードシリアル番号
					
					// POST値が設定されている場合は上書き
					$value = $request->trimValueOf('_pdefconfig');		// ページ定義のウィジェット定義ID
					if (!empty($value)) $this->_defConfigId = $value;
					$value = $request->trimValueOf('_pdefserial');		// ページ定義のレコードシリアル番号
					if (!empty($value)) $this->_defSerial = $value;
				}
				
				$this->_assign($request, $param);
				
				// 管理画面へのアクセスの場合は管理用POST値を設定
				if ($isAdminDirAccess){
					// 画面定義用の情報を戻す
					if (!empty($this->_defSerial)){		// シリアル番号が空のときは、ページ作成からの遷移ではないので、引き継がない
						$this->tmpl->addVar("_widget", "_def_config", $this->_defConfigId);	// ページ定義のウィジェット定義ID
						$this->tmpl->addVar("_widget", "_def_serial", $this->_defSerial);	// ページ定義のレコードシリアル番号
					}
				}
			}
				
			// 各ウィジェットごとのテンプレート処理、テンプレートを使用しないときは出力処理(Ajax等)
			if (method_exists($this, '_postAssign')) $this->_postAssign($request, $param);
			
			// 各ウィジェットごとの追加スクリプトライブラリを取得し、ヘッダに設定
			if (method_exists($this, '_addScriptLibToHead')){
				$scriptLib = $this->_addScriptLibToHead($request, $param);
				
				// ライブラリを追加
				if (!empty($scriptLib)) $this->gPage->addHeadScriptLib($scriptLib);
			}
			// 各ウィジェットごとの追加CSSファイルを取得し、ヘッダに設定
			if (method_exists($this, '_addCssFileToHead')){
				$cssFile = $this->_addCssFileToHead($request, $param);
				
				// ヘッダにCSSを追加
				if (!empty($cssFile)) $this->gPage->addHeadCssFile($cssFile);
			}
			// 各ウィジェットごとの追加Javascriptを取得し、ヘッダに設定
			if (method_exists($this, '_addScriptFileToHead')){
				$scriptFile = $this->_addScriptFileToHead($request, $param);
				
				// ヘッダにJavascriptを追加
				if (!empty($scriptFile)) $this->gPage->addHeadScriptFile($scriptFile);
			}
			// RSS情報を取得し、ヘッダに設定
			if (method_exists($this, '_addRssFileToHead')){
				$rssFileInfo = $this->_addRssFileToHead($request, $param);
				
				// ヘッダにRSSを追加
				if (!empty($rssFileInfo)) $this->gPage->addHeadRssFile($rssFileInfo);
			}
			
			// 各ウィジェットごとのCSSを取得し、ヘッダに設定
			if (method_exists($this, '_addCssToHead')){
				$css = $this->_addCssToHead($request, $param);
				
				// ヘッダにCSSを追加
				if (!empty($css)) $this->gPage->addHeadCss($css);
			}
			// 各ウィジェットごとのJavascriptを取得し、ヘッダに設定
			if (method_exists($this, '_addScriptToHead')){
				$script = $this->_addScriptToHead($request, $param);
				
				// ヘッダにJavascriptを追加
				if (!empty($script)) $this->gPage->addHeadScript($script);
			}
			// 各ウィジェットごとのHead追加文字列を取得し、ヘッダに設定
			if (method_exists($this, '_addStringToHead')){
				$str = $this->_addStringToHead($request, $param);
				
				// ヘッダにJavascriptを追加
				if (!empty($str)) $this->gPage->addHeadString($str);
			}
			// ウィジェットのタイトル設定処理
			if (method_exists($this, '_setTitle')){
				$str = $this->_setTitle($request, $param);
				
				// ヘッダにJavascriptを追加
				if (!empty($str)) $this->gEnv->setCurrentWidgetTitle($str);
			}
			// ヘッダ部メタタグの設定
			if (method_exists($this, '_setHeadMeta')){
				$headData = $this->_setHeadMeta($request, $param);
				if (!empty($headData)){			// タグを設定する場合
					$this->gPage->setHeadSubTitle($headData['title']);
					$this->gPage->setHeadDescription($headData['description']);
					$this->gPage->setHeadKeywords($headData['keywords']);
				}
			}
			if ($templateFile != ''){
				// エラーメッセージ出力
				if ($this->displayMessage) $this->displayMsg();
	
				// HTML生成
				if (!$this->parseCancel) $this->__parse();
			}
		} else {	// メソッドが存在しないときはエラーメッセージを出力
			echo 'method not found: BaseWidgetContainer::_setTemplate()';
		}
	}
	/**
	 * テンプレートファイルの設定
	 */
	function __setTemplate()
	{
		// テンプレートオブジェクト作成
		$this->tmpl = new PatTemplate();
 
		// テンプレート読み込みディレクトリ
		$this->tmpl->setRoot($this->gEnv->getCurrentWidgetTemplatePath());
		
		// エラーメッセージテンプレートを埋め込む
		$this->tmpl->applyInputFilter('ErrorMessage');
		
		// 機能付きタグを変換
		//$this->tmpl->applyInputFilter('FunctionTag');
		
		// コメントを削除
		//$this->tmpl->applyInputFilter('StripComments');
		
		// 管理画面の場合のみの処理
		if ($this->gEnv->isAdminDirAccess()){		// 管理画面へのアクセスのとき
			// 管理画面用パラメータを埋め込む
			$this->tmpl->applyInputFilter('PostParam');
		}
	}
	/**
	 * 出力用の変数に値を設定する
	 * このクラスでは、共通項目を設定
	 */
	function __assign()
	{
		// テンプレートに値を設定
		$now = date("Y/m/d H:i:s");
		
		// システム用変数のデフォルト変換
		$rootUrl = $this->gEnv->getRootUrl();
		$currentWidgetUrl = $this->gEnv->getCurrentWidgetRootUrl();
		if ($this->gEnv->getUseSsl()){		// SSLを使用する場合
			// 現在のページがSSL使用設定になっているかどうかを取得
			$isSslPage = $this->gPage->isSslPage($this->gEnv->getCurrentPageId(), $this->gEnv->getCurrentPageSubId());
			if ($isSslPage){
				//$rootUrl = str_replace('http://', 'https://', $rootUrl);
				//$currentWidgetUrl = str_replace('http://', 'https://', $currentWidgetUrl);
				$rootUrl = $this->gEnv->getSslRootUrl();
				$currentWidgetUrl = $this->gEnv->getCurrentWidgetSslRootUrl();
			}
		}
		$this->tmpl->addVar("_widget", "_ROOT_URL", $rootUrl);
		$this->tmpl->addVar("_widget", "_WIDGET_URL", $currentWidgetUrl);	// ウィジェットのルートディレクトリ
		
		// ヘルプを設定
		/*if ($this->gPage->getUseHelp()){		// ヘルプ表示を行う場合
			// 「_widget」の変換を行う
			$helpKeys = $this->gInstance->getHelpManager()->loadHelp($this->gEnv->getCurrentWidgetId());
			for ($i = 0; $i < count($helpKeys); $i++){
				$key = $helpKeys[$i];
				$helpText = $this->gInstance->getHelpManager()->getHelpText($key);
				$this->tmpl->addVar("_widget", self::HELP_HEAD . $key, $helpText);
			}
		}*/
		
		// デバッグ出力があるときは表示
		if ($this->gEnv->getSystemDebugOut() && method_exists($this,'_debugString')){
			$debugStr = $this->_debugString();
			if (strlen($debugStr) > 0){
				$this->tmpl->addVar("_widget", "_DEBUG", $debugStr);
			}
		}
	}
	/**
	 * 出力データ作成
	 */
	function __parse()
	{
		echo $this->tmpl->getParsedTemplate('_widget');
	}
	/**
	 * テンプレート変換処理中断
	 *
	 * @return 							なし
	 */
	function cancelParse()
	{
		$this->parseCancel = true;			// テンプレート変換処理を中断するかどうか
	}
	/**
	 * ヘルプ文字列を変換
	 *
	 * @param string $templateName		テンプレート名
	 * @return なし
	 */
	function convertHelp($templateName)
	{
		// ヘルプを設定
		$helpKeys = $this->gInstance->getHelpManager()->loadHelp($this->gEnv->getCurrentWidgetId());
		for ($i = 0; $i < count($helpKeys); $i++){
			$key = $helpKeys[$i];
			$helpText = $this->gInstance->getHelpManager()->getHelpText($key);
			$this->tmpl->addVar($templateName, self::HELP_HEAD . $key, $helpText);
		}
	}
	/**
	 * patTemplateを使用した汎用データ変換処理
	 *
	 * ウィジェットのテンプレートディレクトリ内のテンプレートファイルを読み込みデータ変換後、文字列を返す。
	 *
	 * @param string $filename		テンプレートファイル名
	 * @param function $callback	コールバック関数。「callback($tmpl) $tmpl=テンプレートオブジェクト」の形式で呼ばれる。
	 * @param string $templateName	テンプレート名(デフォルトは「_tmpl」)
	 * @return string				変換後データ
	 */
	function getParsedTemplateData($filename, $callback, $templateName = '_tmpl')
	{
		// テンプレートオブジェクト作成
		$tmpl = new PatTemplate();
		
		// テンプレート読み込みディレクトリを設定
		$tmpl->setRoot($this->gEnv->getCurrentWidgetTemplatePath());
		
		// テンプレートファイルを設定
		$tmpl->readTemplatesFromFile($filename);
		
		// コールバック関数を呼び出す
		if (is_callable($callback)) call_user_func($callback, $tmpl);
		
		return $tmpl->getParsedTemplate($templateName);
	}
	/**
	 * 表示用文字列に変換
	 *
	 * @param string $src 		変換元文字列
	 * @param bool $keepTags	HTMLタグを変換するかどうか
	 * @return string			変換後文字列
	 */
	function convertToDispString($src, $keepTags = false)
	{
		// 変換文字「&<>"」
		//return htmlentities($src, ENT_COMPAT, M3_HTML_CHARSET);
		return convertToHtmlEntity($src, $keepTags);
	}
	/**
	 * URLをエンティティ文字に変換
	 */
	function convertUrlToHtmlEntity($src)
	{
		// 変換文字「&<>"'」
		//return htmlspecialchars($src, ENT_QUOTES, M3_HTML_CHARSET);
		return convertUrlToHtmlEntity($src);
	}
	/**
	 * 未入力チェック
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param string $errorMsg		エラー時のメッセージ
	 * @return bool				false未入力、入力誤り
	 */
	function checkInput($str, $title, $errorMsg = '')
	{
		if (strlen($str) == 0){
			if (empty($errorMsg)){
				array_push($this->warningMessage, $title."が入力されていません");
			} else {		// エラーメッセージが設定されている場合
				array_push($this->warningMessage, $errorMsg);
			}
			return false;
		}
		return true;
	}
	/**
	 * メールアドレスチェック
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが許可される文字でない場合、"$title."は半角英数字／ハイフン／アンダースコア／＠以外の入力はできません"を$WarningMessageに追加
	 * メールアドレスが正しい形式か否かもチェックする
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false入力誤り
	 */
	function checkMailAddress($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}
		if (strlen($str) && preg_match("/[^0-9a-zA-Z-.@_]/", $str)){
			array_push($this->warningMessage, $title.
				'は半角英数字／ハイフン／アンダースコア／ピリオド／＠以外の入力はできません');
			return false;
			
		} elseif (strlen($str) && !preg_match("/[\w\d\-\.]+\@[\w\d\-\.]+/", $str)){
			array_push($this->warningMessage, 'この'.$title.'は正しい形式ではありません');
			return false;
		}
		return true;
	}
	/**
	 * IPチェック
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが許可される文字でない場合、"$title."は数値／ピリオド以外の入力はできません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkIp($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}
		if (strlen($str) && preg_match("/[^0-9.]/", $str)){
			array_push($this->warningMessage, $title.
				'は数値／ピリオド以外の入力はできません');
			return false;
		}
		return true;
	}
	/**
	 * URLチェック
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが半角文字ではない場合、"$title."はURLの入力はできません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkUrl($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}
		if (!preg_match('/^(https?|ftp)(:\/\/[-_.!~*\'()\w;\/?:\@&=+\$,%#]+)$/', $str)) {
			array_push($this->warningMessage, $title.
				'はURL以外の入力はできません');
			return false;
		}
		return true;
	}
	/**
	 * 半角文字チェック(整数)
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが半角数値文字ではない場合、$title.'は半角数字以外の入力はできません'を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkNumeric($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}

		if (preg_match("/[^0-9]/", $str)){
			array_push($this->warningMessage, $title.'は半角数字以外の入力はできません');
			return false;
		}
		return true;
	}
	/**
	 * 半角文字チェック(小数)
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが半角文字ではない場合、"$title."は半角数字／ピリオド以外の入力はできません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkNumericF($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}

		if (preg_match("/[^0-9.]/", $str)){
			array_push($this->warningMessage,$title.'は半角数字／ピリオド以外の入力はできません');
			return false;
		}
		return true;
	}
	/**
	 * 半角数値文字チェック(汎用)
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが半角文字ではない場合、"$title."は半角数字／ピリオド以外の入力はできません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @param string $format	入力制限用指定用
	 * @return bool				false未入力、入力誤り
	 */
	function checkNumber($str, $title, $passBlank = false, $format = '')
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}

		if (!is_numeric($str)){
			array_push($this->warningMessage, $title.'は数値のみ入力可能です');
			return false;
		}
		return true;
	}
	/**
	 * パス文字列チェック(スペース不可英数)
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが半角文字ではない場合、"$title."は半角英数字／ハイフン／アンダースコア／スラッシュ以外の入力はできません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkPath($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}
		if (preg_match("/[^0-9a-zA-Z-_\/]/", $str)){
			array_push($this->warningMessage, $title.
				'は半角英数字／ハイフン／アンダースコア／スラッシュ以外の入力はできません');
			return false;
		}
		return true;
	}
	/**
	 * 半角文字チェック(スペース不可英数)
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが半角文字ではない場合、"$title."は半角英数字／ハイフン／アンダースコア以外の入力はできません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @param int $alphaType	英字タイプ(0=大文字小文字許可、1=小文字のみ許可、2=大文字のみ許可)
	 * @return bool				false未入力、入力誤り
	 */
	function checkSingleByte($str, $title, $passBlank = false, $alphaType = 0)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}
		switch ($alphaType){
			case 0:			// 大文字小文字許可
			default:
				if (preg_match("/[^0-9a-zA-Z-_]/", $str)){
					array_push($this->warningMessage, $title . 'は半角英数字／ハイフン／アンダースコア以外の入力はできません');
					return false;
				}
				break;
			case 1:			// 小文字のみ許可
				if (preg_match("/[^0-9a-z-_]/", $str)){
					array_push($this->warningMessage, $title . 'は半角英小文字数字／ハイフン／アンダースコア以外の入力はできません');
					return false;
				}
				break;
			case 2:			// 大文字のみ許可
				if (preg_match("/[^0-9A-Z-_]/", $str)){
					array_push($this->warningMessage, $title . 'は半角英大文字数字／ハイフン／アンダースコア以外の入力はできません');
					return false;
				}
				break;
		}
		return true;
	}
	/**
	 * 半角文字チェック(スペース可英字)
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $strが半角文字ではない場合、"$title."は半角英字／空白以外の入力はできません"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkAlphaSpace($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}
		if (preg_match("/[^a-zA-Z_\ ]/", $str)){
			array_push($this->warningMessage,$title.'は半角英字／空白以外の入力はできません');
			return false;
		}
		return true;
	}
	/**
	 * 入力文字列サイズチェック
	 *
	 * $strが未入力の場合、 "$title.が入力されていません"を$WarningMessageに追加
	 * $byteSizeが最大バイト長よりも大の場合、"$title.'は半角'.$maxSize'.'文字までの入力が可能です'"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param int $maxSize		最大文字数
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkByteSize($str, $title, $maxSize, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
			
		if (!self::checkInput($str, $title)){
			return false;
		}
		if (strlen($str) > $maxSize){
			array_push($this->warningMessage, $title.'は半角'.$maxSize.'文字までの入力が可能です');
			return false;
		}
		return true;
	}
	/**
	 * 日付チェック
	 *
	 * $strが未入力の場合、 "$title.の日付形式が正しくありません。"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkDate($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}

		// セパレータ'/','.'をセパレータ'-'に変換する。
		$str1 = str_replace(array('/','.'), array('-','-'), $str);

		$sprcnt = 0;			// セパレータの数
		$pos = 0;
		while ($sprcnt < 10){
			if ($pos == 0)	$pos = strpos($str1, '-');
			else			$pos = strpos($str1, '-', $pos);
			// Note our use of ===.  Simply == would not work as expected
			// because the position of 'a' was the 0th (first) character.
			if ($pos === false)	break;

			$sprcnt++;			// セパレータの数
			$pos++;
		}

		if ($sprcnt == 0
		 || $sprcnt  > 2){			// セパレータの数
			array_push($this->warningMessage,$title.'は正しい日付の形式ではありません。1');
			return false;
		}
		if ($sprcnt == 2){
			$pos  = strpos( $str1, '-' );
			$yy   = substr( $str1, 0, $pos );
			$str1 = substr( $str1, $pos+1 );
		}
		else{
			$yy = date('Y');
		}
		$pos  = strpos($str1, '-');
		$mm   = substr($str1, 0, $pos);
		$dd   = substr($str1, $pos+1);

		$ret = @checkdate($mm,$dd,$yy);	// 文字列から日付型を作成する。

		if ($ret === false){
			array_push($this->warningMessage,$title.'は正しい日付の形式ではありません。2');
			return false;
		}
		return true;
	}
	/**
	 * 時刻チェック
	 *
	 * $strが未入力の場合、 "$title.の時刻形式が正しくありません。"を$WarningMessageに追加
	 *
	 * @param string $str		表示メッセージ
	 * @param string $title		項目名
	 * @param bool $passBlank	空を正常とするかどうか(true=空を正常とする、false=空の場合はエラーとする)
	 * @return bool				false未入力、入力誤り
	 */
	function checkTime($str, $title, $passBlank=false)
	{
		if ($passBlank && $str == '') return true;
		
		if (!self::checkInput($str, $title)){
			return false;
		}

		// セパレータ':'をセパレータ'-'に変換する。
		$str1 = str_replace(array(':'), array('-'), $str);

		$sprcnt = 0;			// セパレータの数
		$pos = 0;
		while ($sprcnt < 10){
			if ($pos == 0)	$pos = strpos($str1, '-');
			else			$pos = strpos($str1, '-', $pos);
			// Note our use of ===.  Simply == would not work as expected
			// because the position of 'a' was the 0th (first) character.
			if ($pos === false)	break;

			$sprcnt++;			// セパレータの数
			$pos++;
		}

		if ($sprcnt < 0 || 2 < $sprcnt){			// セパレータの数
			array_push($this->warningMessage, $title.'は正しい時刻の形式ではありません。1');
			return false;
		}
		$ret = true;
		list($hh, $mm, $ss) = preg_split('/[:\-]/', $str1);
		$hour = intval($hh);
		$minute = intval($mm);
		$second = intval($ss);
		
		if ($hour < 0 || 23 < $hour) $ret = false;
		if ($minute < 0 || 59 < $minute) $ret = false;
		if ($second < 0 || 59 < $second) $ret = false;
		if (!$ret){
			array_push($this->warningMessage, $title.'は正しい時刻の形式ではありません。2');
			return false;
		}
		return true;
	}
	/**
	 * Timestamp型の値を日付表記に変更
	 *
	 * @param timestamp $datestr	Timestamp型の値
	 * @param string $shortYear		省略形式かどうか
	 * @return string				日付文字列。日付が作成できないときは空文字列を返す。
	 */
	function timestampToDate($datestr, $shortYear = false)
	{
		$yyyy = '';
		$mm = '';
		$dd = '';
		$ret_stat = '';
		list($srcstr, $dummy) = explode(' ', $datestr);
		if (strlen($datestr) == 0) return "";
		list($yyyy, $mm, $dd) = preg_split('/[\/\.\-]/', $srcstr);
		if ($shortYear){	// 短い表記
			$yy = floor($yyyy/100);
			$yy = $yyyy-($yy*100);
			$ret_stat = sprintf("%02s/%02s/%02s", $yy, $mm, $dd);
 		} else {
			$ret_stat = sprintf("%04s/%02s/%02s", $yyyy, $mm, $dd);
		}
  		return $ret_stat;
	}
	/**
	 * Timestamp型の値を時刻表記に変更
	 *
	 * @param timestamp $datestr	Timestamp型の値
	 * @return string				時刻文字列。時刻が作成できないときは空文字列を返す。
	 */
	function timestampToTime($datestr)
	{
		$hh = '';
		$mm = '';
		$ss = '';
		$ret_stat = '';
		list($dummy, $srcstr) = explode(' ', $datestr);// 後半を取得
		if (strlen($datestr) == 0) return false;
		list($hh, $mm, $ss) = preg_split('/[:\-]/', $srcstr);
		$ret_stat = sprintf("%02s:%02s:%02s", $hh, $mm, $ss);
  		return $ret_stat;
	}
	/**
	 * Timestamp型の値から年月日を取得
	 *
	 * @param timestamp $datestr	Timestamp型の値
	 * @param int $year			年
	 * @param int $month			月
	 * @param int $day			日
	 * @return bool					true=成功、false失敗
	 */
	function timestampToYearMonthDay($datestr, &$year, &$month, &$day)
	{
		$yyyy = '';
		$mm = '';
		$dd = '';
		$ret_stat = '';
		list($srcstr, $dummy) = explode(' ', $datestr);
		if (strlen($datestr) == 0) return false;
		list($yyyy, $mm, $dd) = preg_split('/[\/\.\-]/', $srcstr);
		$year = intval($yyyy);
		$month = intval($mm);
		$day = intval($dd);
		return true;
	}
	/**
	 * Timestamp型の値から時分秒を取得
	 *
	 * @param timestamp $datestr	Timestamp型の値
	 * @param int $hour				時
	 * @param int $minute			分
	 * @param int $second			秒
	 * @return bool					true=成功、false失敗
	 */
	function timestampToHourMinuteSecond($datestr, &$hour, &$minute, &$second)
	{
		$hh = '';
		$mm = '';
		$ss = '';
		$ret_stat = '';
		list($dummy, $srcstr) = explode(' ', $datestr);// 後半を取得
		if (strlen($datestr) == 0) return false;
		list($hh, $mm, $ss) = preg_split('/[:\-]/', $srcstr);
		$hour = intval($hh);
		$minute = intval($mm);
		$second = intval($ss);
		return true;
	}
	/**
	 * 簡易日付(mm/dd, yy/m/d,etc)形式で入力された文字列を正式な日付表現(yyyy/mm/dd)に変換
	 *
	 * @param timestamp $datestr	Timestamp型の値
	 * @return string				日付文字列。日付が作成できないときは空文字列を返す。
	 */
	function convertToProperDate($datestr)
	{
		$yyyy = '';
		$mm = '';
		$dd = '';
		$ret_stat = '';
		list($srcstr, $dummy) = explode(' ', $datestr);
		if (strlen($datestr) == 0) return "";
		$srcarray = preg_split('/[\/\.\-]/', $srcstr);
		
		//月日しか入力されていないときは、年を追加
		if (count($srcarray) == 2){	// 月日のみ入力
			array_unshift($srcarray, date("Y"));
		} else if (count($srcarray) == 1){	// 日のみ入力
			array_unshift($srcarray, date("m"));
			array_unshift($srcarray, date("Y"));
		}

		// 年月日を取得
		list($yyyy, $mm, $dd) = $srcarray;

		// 年号が4桁ないときは、4桁にする
		if (strlen($yyyy) < 4) $yyyy += 2000;

		$ret_stat = sprintf("%04s/%02s/%02s", $yyyy, $mm, $dd);
  		return $ret_stat;
	}
	/**
	 * 簡易時刻(hh, hh:mm, hh:mm:ss, etc)形式で入力された文字列を正式な時刻表現(hh:mm:ss)に変換
	 *
	 * @param string $src			変換元時刻文字列
	 * @param int $format			出力フォーマット(0=時分秒(デフォルト)、1=時分、2=時のみ)
	 * @return string				時刻文字列。時刻が作成できないときは空文字列を返す。
	 */
	function convertToProperTime($src, $format = 0)
	{
		$hh = '';
		$mm = '';
		$ss = '';
		$ret_stat = '';
		$srcstr = trim($src);
		if (strlen($srcstr) == 0) return "";

		list($hh, $mm, $ss) = preg_split('/[:]/', $srcstr);
		$hour = intval($hh);
		$minute = intval($mm);
		$second = intval($ss);
		
		$ret = true;
		if ($hour < 0 || 23 < $hour) $ret = false;
		if ($minute < 0 || 59 < $minute) $ret = false;
		if ($second < 0 || 59 < $second) $ret = false;

		if ($ret){
			switch ($format){
				case 0:			// 時分秒
				default:
					$ret_stat = sprintf("%02s:%02s:%02s", $hour, $minute, $second);
					break;
				case 1:			// 時分
					$ret_stat = sprintf("%02s:%02s", $hour, $minute);
					break;
				case 2:			// 時のみ
					$ret_stat = sprintf("%02s", $hour);
					break;
			}
  			return $ret_stat;
		} else {
			return '';
		}
	}
	/**
	 * 年月(yyyy/mm)から末日を求める
	 *
	 * @param string $strYM			年月
	 * @return int					末日
	 */
	function getLastDayOfMonth($strYM)
	{
		// セパレータ'/','.'をセパレータ'-'に変換する。
		$strYM = str_replace(array('/','.'), array('-','-'), $strYM);
		$pos   = strpos( $strYM, '-' );
		$yy    = substr( $strYM, 0, $pos );
		$mm    = substr( $strYM, $pos+1 );

		switch( $mm ){
		// 検索
		case 1 :
		case 3 :
		case 5 :
		case 7 :
		case 8 :
		case 10 :
		case 12 :
			return 31;
		case 4 :
		case 6 :
		case 9 :
		case 11 :
			return 30;
		case 2 :
			$doy = date('z', strtotime("$yy-12-31"));	// 0-364(365=URUU)
			if( $doy == 364)return 28;
			else			return 29;
		}
	}
	/**
	 * 年月日(yyyy/mm/dd)から前日を求める
	 *
	 * @param string $strYMD		年月日
	 * @return string				前日
	 */
	function getForeDay($srcstr)
	{
		list($yyyy, $mm, $dd) = preg_split('/[\/\.\-]/', $srcstr);
		return date("Y/m/d", mktime(0, 0, 0, $mm, $dd - 1, $yyyy));
	}
	/**
	 * 年月日(yyyy/mm/dd)から翌日を求める
	 *
	 * @param string $strYMD		年月日
	 * @return string				翌日
	 */
	function getNextDay($srcstr)
	{
		list($yyyy, $mm, $dd) = preg_split('/[\/\.\-]/', $srcstr);
		return date("Y/m/d", mktime(0, 0, 0, $mm, $dd + 1, $yyyy));
	}
	/**
	 * 年月日(yyyy/mm/dd)から前月を求める
	 *
	 * @param string $strYMD		年月日
	 * @return string				前月
	 */
	function getForeMonth($srcstr)
	{
		list($yyyy, $mm) = preg_split('/[\/\.\-]/', $srcstr);
		return date("Y/m", mktime(0, 0, 0, $mm -1, 1, $yyyy));
	}
	/**
	 * 年月日(yyyy/mm/dd)から翌月を求める
	 *
	 * @param string $strYMD		年月日
	 * @return string				翌月
	 */
	function getNextMonth($srcstr)
	{
		list($yyyy, $mm) = preg_split('/[\/\.\-]/', $srcstr);
		return date("Y/m", mktime(0, 0, 0, $mm +1, 1, $yyyy));
	}
	/**
	 * タイムスタンプ型日時をHTML表示用のシステム標準のフォーマットに変換
	 *
	 * @param timestamp $src		変換するデータ
	 * @param int $type				日付タイプ(0=年ロングフォーマット、1=年ショートフォーマット、10=年なし)
	 * @param int $timeType			時間タイプ(0=時分秒、1=時分、2=時)
	 * @return string				変換後データ、初期化値のときは空文字列を返す
	 */
	function convertToDispDateTime($src, $type = 0, $timeType = 0)
	{
		// 接続するDBに応じて初期化値を判断
		$time = strtotime($src);
		if ($time == strtotime($this->gEnv->getInitValueOfTimestamp())) return '';
		
		$dateFormat = '';
		$timeFormat = '';
		
		// 日付フォーマット
		switch ($type){
			case 0:
			default:
				$dateFormat = 'Y/m/d';
				break;
			case 1:		// 年ショートフォーマット
				$dateFormat = 'y/m/d';
				break;
			case 10:		// 年なし
				$dateFormat = 'm/d';
				break;
		}
		
		// 時間フォーマット
		switch ($timeType){
			case 0:
			default:
				$timeFormat = 'H:i:s';
				break;
			case 10:		// 時分
				$timeFormat = 'H:i';
				break;
			case 20:		// 時のみ
				$timeFormat = 'H';
				break;
		}
		/*if ($type == 0){	// ロングフォーマット(yyyy/mm/dd hh:mm:ss)
			return date("Y/m/d H:i:s", $time);
		} else if ($type == 1){	// ロングフォーマット(yyyy/mm/dd hh:mm)
			return date("Y/m/d H:i", $time);
		} else if ($type == 10){			// ショートフォーマット(yy/mm/dd hh:mm:ss)
			return date("y/m/d H:i:s", $time);
		}*/
		
		return date($dateFormat . ' ' . $timeFormat, $time);
	}
	/**
	 * タイムスタンプ型日時をHTML表示用のシステム標準のフォーマットに変換
	 *
	 * @param timestamp $src		変換するデータ
	 * @param int $type				0=ロングフォーマット、1=ショートフォーマット
	 * @return string				変換後データ、初期化値のときは空文字列を返す
	 */
	function convertToDispDate($src, $type = 0)
	{
		// 接続するDBに応じて初期化値を判断
		$time = strtotime($src);
		if ($time == strtotime($this->gEnv->getInitValueOfTimestamp())) return '';

		if ($type == 0){	// ロングフォーマット(yyyy/mm/dd)
			return date("Y/m/d", $time);
		} else {			// ショートフォーマット(yy/mm/dd)
			return date("y/m/d", $time);
		}
	}
	/**
	 * タイムスタンプ型日時をHTML表示用のシステム標準のフォーマットに変換
	 *
	 * @param timestamp $src		変換するデータ
	 * @param int $type				0=ロングフォーマット、1=ショートフォーマット
	 * @return string				変換後データ、初期化値のときは空文字列を返す
	 */
	function convertToDispTime($src, $type = 0)
	{
		// 接続するDBに応じて初期化値を判断
		$time = strtotime($src);
		if ($time == strtotime($this->gEnv->getInitValueOfTimestamp())) return '';
		
		// 時刻部分を取得
		$time = strtotime($this->timestampToTime($src));
		
		if ($type == 0){	// ロングフォーマット(hh:mm:ss)
			return date("H:i:s", $time);
		} else {			// ショートフォーマット(hh:mm)
			return date("H:i", $time);
		}
	}
	/**
	 * タイムスタンプ型日時をテキスト表示用のシステム標準のフォーマットに変換
	 *
	 * @param timestamp $src		変換するデータ
	 * @param int $type				0=ロングフォーマット、1=ショートフォーマット
	 * @return string				変換後データ、初期化値のときは空文字列を返す
	 */
	function convertToDateTimeString($src, $type = 0)
	{
		// 接続するDBに応じて初期化値を判断
		$time = strtotime($src);
		if ($time == strtotime($this->gEnv->getInitValueOfTimestamp())) return '';
		
		if ($type == 0){	// ロングフォーマット(yyyy/mm/dd hh:mm:ss)
			return date("Y/m/d H:i:s", $time);
		} else {			// ショートフォーマット(yy/mm/dd hh:mm:ss)
			return date("y/m/d H:i:s", $time);
		}
	}
	/**
	 * タイムスタンプ型日時をテキスト表示用のシステム標準のフォーマットに変換
	 *
	 * @param timestamp $src		変換するデータ
	 * @param int $type				0=ロングフォーマット、1=ショートフォーマット
	 * @return string				変換後データ、初期化値のときは空文字列を返す
	 */
	function convertToDateString($src, $type = 0)
	{
		// 接続するDBに応じて初期化値を判断
		$time = strtotime($src);
		if ($time == strtotime($this->gEnv->getInitValueOfTimestamp())) return '';

		if ($type == 0){	// ロングフォーマット(yyyy/mm/dd)
			return date("Y/m/d", $time);
		} else {			// ショートフォーマット(yy/mm/dd)
			return date("y/m/d", $time);
		}
	}
	/**
	 * テキストデータを表示用のテキストに変換
	 *
	 * 変換内容　・改行コードを<br />に変換
	 *
	 * @param string $src			変換するデータ
	 * @return string				変換後データ
	 */
	function convertToPreviewText($src)
	{
		// 改行コードをbrタグに変換
		return HtmlEdit::convLineBreakToBr($src);
	}
	/**
	 * Magic3マクロを変換してHTMLを作成
	 *
	 * ・デフォルトでマクロ変換した文字列に改行が含まれるときは改行をbrに変換する
	 *
	 * @param string $src			変換するデータ
	 * @param bool $convBr			キーワード変換部分の改行コードをBRタグに変換するかどうか
	 * @return string				変換後データ
	 */
	function convertM3ToHtml($src, $convBr=true)
	{
		// URLを求める
		$rootUrl = $this->gEnv->getRootUrlByCurrentPage();
		$widgetUrl = str_replace($this->gEnv->getRootUrl(), $rootUrl, $this->gEnv->getCurrentWidgetRootUrl());
		
		// パスを変換
		$dest = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $rootUrl, $src);// アプリケーションルートを変換
		$dest = str_replace(M3_TAG_START . M3_TAG_MACRO_WIDGET_URL . M3_TAG_END, $widgetUrl, $dest);// ウィジェットルートを変換
		
		// 登録したキーワードを変換
		$this->gInstance->getTextConvManager()->convByKeyValue($dest, $dest, $convBr/*改行コーをbrタグに変換*/);
		
		// 残っているMagic3タグ削除
		$dest = $this->gInstance->getTextConvManager()->deleteM3Tag($dest);
		return $dest;
	}
	/**
	 * 値のデータをCSV用のエスケープデータに変換
	 *
	 * @param string $src			変換するデータ
	 * @return string				変換後データ
	 */
	function convertToEscapedCsv($src)
	{
		if (is_numeric($src)){
			return $src;
		} else {
			return '"' . $src . '"';
		}
	}
	/**
	 * メッセージ表示
	 */
	function displayMsg()
	{
		// メッセージがある場合はメッセージタグを表示
		if ($this->getMsgCount() > 0){
			$this->tmpl->setAttribute('_messages', 'visibility', 'visible');
		} else {
			return;
		}
		
		// アプリケーションエラー
		if (count($this->errorMessage) > 0){
			$this->tmpl->setAttribute('_error_message', 'visibility', 'visible');	// メッセージ表示タグを表示
			
			foreach ($this->errorMessage as $value) {
				$row = array(
					'message' => $value
				);
				$this->tmpl->addVars('_error_message', $row);
				$this->tmpl->parseTemplate('_error_message', 'a');
			}
		}
		// ユーザエラー
		if (count($this->warningMessage) > 0){
			$this->tmpl->setAttribute('_warning_message', 'visibility', 'visible');		// メッセージ表示タグを表示
			
			foreach ($this->warningMessage as $value) {
				$row = array(
					'message' => $value
				);
				$this->tmpl->addVars('_warning_message', $row);
				$this->tmpl->parseTemplate('_warning_message', 'a');
			}
		}
		// ガイダンス
		if (count($this->guidanceMessage) > 0){
			$this->tmpl->setAttribute('_guidance_message', 'visibility', 'visible');			// メッセージ表示タグを表示
			
			foreach ($this->guidanceMessage as $value) {
				$row = array(
					'message' => $value
				);
				$this->tmpl->addVars('_guidance_message', $row);
				$this->tmpl->parseTemplate('_guidance_message', 'a');				
			}
		}
		// 追加属性を設定
		if (!empty($this->messageAttr)) $this->tmpl->addVar('_messages', 'attr', $this->messageAttr);
	}
	/**
	 * メッセージをクリアする
	 */
	function clearMsg()
	{
		// アプリケーションエラー
		while (count($this->errorMessage)){
			array_shift($this->errorMessage);
		}
		// ユーザ操作のエラー
		while (count($this->warningMessage)){
			array_shift($this->warningMessage);
		}
		// ガイダンス
		while (count($this->guidanceMessage)){
			array_shift($this->guidanceMessage);
		}
	}
	/**
	 * メッセージテーブルにメッセージを設定する
	 *
	 * @param int $type		エラーメッセージのタイプ。
	 * @param string $msg	メッセージ
	 * @return 				なし
	 */
	function setMsg($type, $msg)
	{
		if($type == self::MSG_APP_ERR){	// アプリケーションエラー
			array_push($this->errorMessage, $msg);
		} else if($type == self::MSG_USER_ERR){	// ユーザ操作のエラー
			array_push($this->warningMessage, $msg);
		} else if($type == self::MSG_GUIDANCE){	// ガイダンス
			array_push($this->guidanceMessage, $msg);
		}
	}
	/**
	 * メッセージを追加する
	 *
	 * @param array $errorMessage		エラーメッセージ
	 * @param array $warningMessage		ユーザ操作のエラー
	 * @param array $guidanceMessage	ガイダンス
	 * @return 				なし
	 */
	function addMsg($errorMessage, $warningMessage, $guidanceMessage)
	{
		$this->errorMessage		= array_merge($this->errorMessage, $errorMessage);		// アプリケーションエラー
		$this->warningMessage	= array_merge($this->warningMessage, $warningMessage);	// ユーザ操作のエラー
		$this->guidanceMessage	= array_merge($this->guidanceMessage, $guidanceMessage);	// ガイダンス
	}
	/**
	 * グローバルメッセージを追加取得する
	 *
	 * @return 				なし
	 */
	function getGlobalMsg()
	{
		$this->addMsg($this->gInstance->getMessageManager()->getErrorMessage(), $this->gInstance->getMessageManager()->getWarningMessage(), $this->gInstance->getMessageManager()->getGuidanceMessage());
	}
	/**
	 * メッセージテーブルにアプリケーションエラーメッセージを設定する
	 *
	 * @param string $msg	メッセージ
	 * @return 				なし
	 */
	function setAppErrorMsg($msg)
	{
		array_push($this->errorMessage, $msg);
	}
	/**
	 * メッセージテーブルにユーザ操作エラーメッセージを設定する
	 *
	 * @param string $msg	メッセージ
	 * @return 				なし
	 */
	function setUserErrorMsg($msg)
	{
		array_push($this->warningMessage, $msg);
	}
	/**
	 * メッセージテーブルにガイダンスメッセージを設定する
	 *
	 * @param string $msg	メッセージ
	 * @return 				なし
	 */
	function setGuidanceMsg($msg)
	{
		array_push($this->guidanceMessage, $msg);
	}
	/**
	 * メッセージ数を返す
	 *
	 * @param int $type		メッセージのタイプ。1=ErrorMessage,2=WarningMessage,3=GuidanceMessage,省略=すべてのメッセージ数
	 * @return 				なし
	 */
	function getMsgCount($type = 0)
	{
		if ($type == 0){		// すべてのメッセージ数
			return count($this->errorMessage) + count($this->warningMessage) + count($this->guidanceMessage);
		} else if ($type == self::MSG_APP_ERR){	// アプリケーションエラー
			return count($this->errorMessage);
		} else if($type == self::MSG_USER_ERR){	// ユーザ操作のエラー
			return count($this->warningMessage);
		} else if($type == self::MSG_GUIDANCE){// ガイダンス
			return count($this->guidanceMessage);
		}
	}
	/**
	 * メッセージが存在するかを返す
	 *
	 * @return 				true=メッセージが存在、false=メッセージなし
	 */
	function isExistsMsg()
	{
		if (count($this->errorMessage) + count($this->warningMessage) + count($this->guidanceMessage) > 0){
			return true;
		} else {
			return false;
		}
	}
	/**
	 * メッセージ表示タグに追加属性を設定
	 *
	 * @param string $attr	属性
	 * @return 				なし
	 */
	function setMessageAttr($attr)
	{
		$this->messageAttr = $attr;
	}
	/**
	 * パスワード生成
	 *
	 * システム共通でパスワード生成
	 *
	 * @return string				生成したパスワード
	 */
	function makePassword()
	{
		if (M3_SYSTEM_DEMO){		// デモモードのときは簡易パスワードを使用
			$password = 'demo';
		} else {
			$password = makePassword(self::PASSWORD_LENGTH);
		}
		return $password;
	}
	/**
	 * ウィジェットパラメータオブジェクトを取得
	 *
	 * @return object			ウィジェットオブジェクト。取得できないときはnull。
	 */
	function getWidgetParamObj()
	{
		$serializedParam = $this->gInstance->getSytemDbObject()->getWidgetParam($this->gEnv->getCurrentWidgetId());
		if (empty($serializedParam)){
			return null;
		} else {
			return unserialize($serializedParam);
		}
	}
	/**
	 * ウィジェットパラメータオブジェクトを定義IDで取得
	 *
	 * @param int $id		定義ID
	 * @return object		ウィジェットオブジェクト。取得できないときはnull。
	 */
	function getWidgetParamObjByConfigId($id)
	{
		$serializedParam = $this->_db->getWidgetParam($this->gEnv->getCurrentWidgetId(), $id);
		if (empty($serializedParam)){
			return null;
		} else {
			return unserialize($serializedParam);
		}
	}
	/**
	 * ウィジェットパラメータオブジェクトを更新
	 *
	 * @param object $obj		格納するウィジェットパラメータオブジェクト
	 * @return bool				true=更新成功、false=更新失敗
	 */
	function updateWidgetParamObj($obj)
	{
		if (empty($obj)){
			$updateObj = null;
		} else {
			$updateObj = serialize($obj);
		}
		$ret = $this->gInstance->getSytemDbObject()->updateWidgetParam($this->gEnv->getCurrentWidgetId(), $updateObj, $this->gEnv->getCurrentUserId());
		return $ret;
	}
	/**
	 * ウィジェットパラメータオブジェクトを定義IDで更新
	 *
	 * @param int $id			定義ID
	 * @param object $obj		格納するウィジェットパラメータオブジェクト
	 * @return bool				true=更新成功、false=更新失敗
	 */
	function updateWidgetParamObjByConfigId($id, $obj)
	{
		$now = date("Y/m/d H:i:s");	// 現在日時
		if (empty($obj)){
			$updateObj = null;
		} else {
			$updateObj = serialize($obj);
		}
		$ret = $this->gInstance->getSytemDbObject()->updateWidgetParam($this->gEnv->getCurrentWidgetId(), $updateObj, $this->gEnv->getCurrentUserId(), $now, $id);
		return $ret;
	}
	/**
	 * ウィジェットパラメータオブジェクトを取得(定義ID付き)
	 *
	 * @param bool $withZeroId	定義ID=0のオブジェクトも取得
	 * @return array			ウィジェットオブジェクトの配列。
	 */
	function getWidgetParamObjectWithId($withZeroId = false)
	{
		// 該当するウィジェットのパラメータオブジェクトをすべて取得
		$ret = $this->gInstance->getSytemDbObject()->getAllWidgetParam($this->gEnv->getCurrentWidgetId(), $rows);
		if ($ret){
			$params = array();
			for ($i = 0; $i < count($rows); $i++){
				$newObj = new stdClass;
				$newObj->id = $rows[$i]['wp_config_id'];
				if (!$withZeroId && empty($newObj->id)) continue;			// 定義ID=0のデータは取得しない
				$newObj->object = unserialize($rows[$i]['wp_param']);		// オブジェクト化
				$params[] = $newObj;
			}
			return $params;
		} else {
			return null;
		}
	}
	/**
	 * ウィジェットパラメータオブジェクトを更新(定義ID付き)
	 *
	 * @param object $param		定義IDとオブジェクトをメンバーに持つオブジェクト。定義ID=-1のとき新規追加で、実行後に新規の定義IDが返る。オブジェクトが空のときは削除。
	 * @return bool				true=更新成功、false=更新失敗
	 */
	function updateWidgetParamObjectWithId(&$param)
	{
		$now = date("Y/m/d H:i:s");	// 現在日時
		$configId = $param->id;
		if (empty($param->object)){
			$obj = null;
		} else {
			$obj = serialize($param->object);
		}
		$ret = $this->gInstance->getSytemDbObject()->updateWidgetParam($this->gEnv->getCurrentWidgetId(), $obj, $this->gEnv->getCurrentUserId(), $now, $configId);
		if ($param->id == -1 && $ret) $param->id = $configId;
		return $ret;
	}
	/**
	 * 管理画面起動時のウィジェット定義ID、画面定義シリアル番号を取得
	 *
	 * @param string 	$defSerial			画面定義シリアル番号
	 * @param string 	$defConfigId		ウィジェット定義ID
	 * @param object	$paramObj			ウィジェットパラメータオブジェクトの配列
	 * @param bool $withZeroId				定義ID=0のオブジェクトも取得
	 * @return								なし
	 */
	function startPageDefParam(&$defSerial, &$defConfigId, &$paramObj, $withZeroId = false)
	{
		$defSerial = $this->_defSerial;
		$defConfigId = $this->_defConfigId;
		$paramObj = $this->getWidgetParamObjectWithId($withZeroId);
	}
	/**
	 * 管理画面起動時のウィジェット定義ID、画面定義シリアル番号を更新
	 *
	 * @param string 	$defSerial			画面定義シリアル番号
	 * @param string 	$defConfigId		ウィジェット定義ID
	 * @param object	$paramObj			ウィジェットパラメータオブジェクトの配列
	 * @return								なし
	 */
	function endPageDefParam(&$defSerial, &$defConfigId, &$paramObj)
	{
		//$this->_defSerial = $defSerial;		// シリアル番号は更新しない
		$this->_defConfigId = $defConfigId;
	}
	/**
	 * ウィジェットパラメータオブジェクトを追加
	 *
	 * @param string 	$defSerial			画面定義シリアル番号
	 * @param string 	$defConfigId		ウィジェット定義ID
	 * @param object	$paramObj			ウィジェットパラメータオブジェクトの配列
	 * @param object	$newObj				新規追加パラメータオブジェクト(nameメンバーに設定名をセット)
	 * @param string 	$menuId				メニューID(メニューの場合)
	 * @return bool							true=成功、false=失敗
	 */
	function addPageDefParam(&$defSerial, &$defConfigId, &$paramObj, $newObj, $menuId = '')
	{
		$newParam = new stdClass;
		$newParam->id = -1;		// 新規追加
		$newParam->object = $newObj;
	
		// ウィジェットパラメータオブジェクト更新
		$ret = $this->updateWidgetParamObjectWithId($newParam);
		if ($ret){
			$paramObj[] = $newParam;		// 新規定義を追加
			$defConfigId = $newParam->id;		// 定義定義IDを更新
		}
		
		// 画面定義更新
		if ($ret && !empty($defSerial)){		// 画面作成から呼ばれている場合のみ更新
			$ret = $this->_db->updateWidgetConfigId($this->gEnv->getCurrentWidgetId(), $defSerial, $defConfigId, $newObj->name, $menuId);
		}
		
		// キャッシュをクリア
		$this->gCache->clearCacheByWidgetConfigId($this->gEnv->getCurrentWidgetId(), $defConfigId);
		
		// 親ウィンドウを更新
		$this->gPage->updateParentWindow($defSerial);
		return $ret;
	}
	/**
	 * ウィジェットパラメータオブジェクトを更新
	 *
	 * @param string 	$defSerial			画面定義シリアル番号
	 * @param string 	$defConfigId		ウィジェット定義ID
	 * @param object	$paramObj			ウィジェットパラメータオブジェクトの配列
	 * @param int		$id					定義ID
	 * @param object	$updateObj			更新パラメータオブジェクト
	 * @param string 	$menuId				メニューID(メニューの場合)
	 * @return bool							true=成功、false=失敗
	 */
	function updatePageDefParam(&$defSerial, &$defConfigId, &$paramObj, $id, $updateObj, $menuId = '')
	{
		// 該当項目を更新
		$ret = false;
		for ($i = 0; $i < count($paramObj); $i++){
			$configId	= $paramObj[$i]->id;// 定義ID
			if ($configId == $id){
				// ウィジェットオブジェクト更新
				$paramObj[$i]->object = $updateObj;
				
				// ウィジェットパラメータオブジェクトを更新
				$ret = $this->updateWidgetParamObjectWithId($paramObj[$i]);
				if ($ret) $defConfigId = $id;		// 定義定義IDを更新
				break;
			}
		}
		// 画面定義更新
		if ($ret && !empty($defSerial)){		// 画面作成から呼ばれている場合のみ更新
			$ret = $this->_db->updateWidgetConfigId($this->gEnv->getCurrentWidgetId(), $defSerial, $id, $updateObj->name, $menuId);
		}
		
		// キャッシュをクリア
		$this->gCache->clearCacheByWidgetConfigId($this->gEnv->getCurrentWidgetId(), $id);
		
		// 親ウィンドウを更新
		$this->gPage->updateParentWindow($defSerial);
		return $ret;
	}
	/**
	 * ウィジェットパラメータオブジェクトを削除
	 *
	 * @param string 	$defSerial			画面定義シリアル番号
	 * @param string 	$defConfigId		ウィジェット定義ID
	 * @param object	$paramObj			ウィジェットパラメータオブジェクトの配列
	 * @param int		$idArray			削除する定義ID
	 * @return bool							true=成功、false=失敗
	 */
	function delPageDefParam(&$defSerial, &$defConfigId, &$paramObj, $idArray)
	{
		$saveDefConfigId = $defConfigId;		// 削除対象を退避
		$delConfig = false;// 定義IDが削除対象かどうか
		$ret = false;
		for ($i = 0; $i < count($paramObj); $i++){
			$configId = $paramObj[$i]->id;// 定義ID
			if (in_array($configId, $idArray)){		// 削除対象のとき
				$newParam = new stdClass;
				$newParam->id = $configId;
				$newParam->object = null;		// 削除処理
				$ret = $this->updateWidgetParamObjectWithId($newParam);
				if ($ret){
					if ($configId == $defConfigId) $delConfig = true;
				} else {
					break;
				}
			}
		}
		// データ再設定
		if ($ret){
			if ($delConfig) $defConfigId = 0;
			
			// パラメータオブジェクトを再取得
			$paramObj = $this->getWidgetParamObjectWithId();
		}
		
		// 画面定義更新
		if ($ret && !empty($defSerial) && $delConfig){		// 画面作成から呼ばれている場合のみ更新
			$ret = $this->_db->updateWidgetConfigId($this->gEnv->getCurrentWidgetId(), $defSerial, 0, '');
		}
		
		// キャッシュをクリア
		$this->gCache->clearCacheByWidgetConfigId($this->gEnv->getCurrentWidgetId(), $saveDefConfigId);
		
		// 親ウィンドウを更新
		$this->gPage->updateParentWindow($defSerial);
		return $ret;
	}
	/**
	 * ウィジェットパラメータオブジェクトを取得
	 *
	 * @param string 	$defSerial			画面定義シリアル番号
	 * @param string 	$defConfigId		ウィジェット定義ID
	 * @param object	$paramObj			ウィジェットパラメータオブジェクトの配列
	 * @param int		$id					定義ID
	 * @param object	$destObj			取得パラメータオブジェクト
	 * @return bool							true=成功、false=失敗
	 */
	function getPageDefParam(&$defSerial, &$defConfigId, &$paramObj, $id, &$destObj)
	{
		for ($i = 0; $i < count($paramObj); $i++){
			$configId	= $paramObj[$i]->id;// 定義ID
			if ($configId == $id){
				$destObj = $paramObj[$i]->object;
				return true;
			}
		}
		return false;
	}
	/**
	 * 新規用のウィジェット定義IDを取得
	 *
	 * @param object	$paramObj			ウィジェットパラメータオブジェクトの配列
	 * @return int							新規用のウィジェットID
	 */
	function getTempConfigId($paramObj)
	{
		$maxId = 0;
		for ($i = 0; $i < count($paramObj); $i++){
			$configId	= $paramObj[$i]->id;// 定義ID
			if ($configId > $maxId) $maxId = $configId;
		}
		$maxId++;
		return $maxId;
	}
	/**
	 * ウィジェット専用セッション値を設定
	 *
	 * ウィジェット専用セッションは同一ウィジェット内でのみ使用するセッションである。
	 * 「ウィジェットID:キー名」形式のキーでセッションに格納する。
	 *
	 * @param string $key		セッション格納用のキー
	 * @param string $default	値を設定しない場合のデフォルト値
	 * @return なし
	 */
	function setWidgetSession($key, $default = '')
	{
		$keyName = $this->gEnv->getCurrentWidgetId() . ':' . $key;
		$this->gRequest->setSessionValue($keyName, $default);
	}
	/**
	 * ウィジェット専用セッション値を取得
	 *
	 * ウィジェット専用セッションは同一ウィジェット内でのみ使用するセッションである。
	 * 「ウィジェットID:キー名」形式のキーでセッションに格納する。
	 *
	 * @param string $key		セッション格納用のキー
	 * @param string $default	値が存在しない場合のデフォルト値
	 * @return string			値
	 */
	function getWidgetSession($key, $default = '')
	{
		$keyName = $this->gEnv->getCurrentWidgetId() . ':' . $key;
		return $this->gRequest->getSessionValue($keyName, $default);
	}
	/**
	 * インナーウィジェットを出力を取得
	 *
	 * @param string $id		ウィジェットID+インナーウィジェットID
	 * @param string $configId	インナーウィジェット定義ID
	 * @param bool $isAdmin		管理者機能(adminディレクトリ以下)かどうか
	 * @return string 			出力内容
	 */
	function getIWidgetContent($id, $configId, $isAdmin = false)
	{
		$ret = $this->gPage->commandIWidget(10/*コンテンツ取得*/, $id, $configId, $paramObj, $optionParamObj, $resultObj, $content, $isAdmin);
		return $content;
	}
	/**
	 * インナーウィジェットにパラメータを設定
	 *
	 * @param string $id				ウィジェットID+インナーウィジェットID
	 * @param string $configId			インナーウィジェット定義ID
	 * @param string $param				シリアル化したパラメータオブジェクト
	 * @param object $optionParamObj	追加パラメータオブジェクト
	 * @param bool $isAdmin				管理者機能(adminディレクトリ以下)かどうか
	 * @return string 					出力内容
	 */
	function setIWidgetParam($id, $configId, $param, $optionParamObj, $isAdmin = false)
	{
		$paramObj = unserialize($param);			// パラメータをオブジェクト化
		$ret = $this->gPage->commandIWidget(0/*パラメータ設定*/, $id, $configId, $paramObj, $optionParamObj, $resultObj, $content, $isAdmin);
		return $ret;
	}
	/**
	 * インナーウィジェットのパラメータを入力値から更新
	 *
	 * @param string $id				ウィジェットID+インナーウィジェットID
	 * @param string $configId			インナーウィジェット定義ID
	 * @param string $param				シリアル化したパラメータオブジェクト
	 * @param object $optionParamObj	追加パラメータオブジェクト
	 * @param bool $isAdmin				管理者機能(adminディレクトリ以下)かどうか
	 * @return string 					出力内容
	 */
	function updateIWidgetParam($id, $configId, &$param, &$optionParamObj, $isAdmin = false)
	{
		$ret = $this->gPage->commandIWidget(1/*パラメータ更新*/, $id, $configId, $paramObj, $optionParamObj, $resultObj, $content, $isAdmin);
		$param = serialize($paramObj);		// シリアル化
		return $ret;
	}
	/**
	 * インナーウィジェットにパラメータを設定し計算処理を行う
	 *
	 * @param string $id				ウィジェットID+インナーウィジェットID
	 * @param string $configId			インナーウィジェット定義ID
	 * @param string $param				シリアル化したパラメータオブジェクト
	 * @param object $optionParamObj	追加パラメータオブジェクト
	 * @param bool $isAdmin				管理者機能(adminディレクトリ以下)かどうか
	 * @return string 					出力内容
	 */
	function calcIWidgetParam($id, $configId, $param, &$optionParamObj, &$resultObj, $isAdmin = false)
	{
		$paramObj = unserialize($param);			// パラメータをオブジェクト化
		$ret = $this->gPage->commandIWidget(2/*計算*/, $id, $configId, $paramObj, $optionParamObj, $resultObj, $content, $isAdmin);
		return $ret;
	}
	/**
	 * ウィジェット指定でコマンドを実行するためのURLを作成
	 *
	 * @param string $widgetId	コマンドを送信先ウィジェット
	 * @param string $param		送信先ウィジェットに渡すURLパラメータ
	 * @return string			作成したURL
	 */
	function createCmdUrlToWidget($widgetId, $param)
	{
		return $this->gPage->createWidgetCmdUrl($widgetId, $this->gEnv->getCurrentWidgetId(), $param);
	}
	/**
	 * 管理画面起動時の定義IDを取得
	 *
	 * @param RequestManager 	$request		HTTPリクエスト処理クラス
	 * @return int								定義ID(0以上)
	 */
	function getPageDefConfigId($request)
	{
		$configId = 0;				// デフォルト定義ID
		
		if (!empty($act)) return $configId;		// 初期呼び出し時以外は終了
		
		$value = $request->trimValueOf(M3_REQUEST_PARAM_PAGE_DEF_CONFIG_ID);
		if ($value != '') $configId = intval($value);
		if ($configId < 0) $configId = 0;		// エラー値を修正
		return $configId;
	}
	/**
	 * 管理画面起動時の画面定義シリアル番号を取得
	 *
	 * @param RequestManager 	$request		HTTPリクエスト処理クラス
	 * @return int								シリアル番号(0以上)
	 */
	function getPageDefSerial($request)
	{
		$serial = 0;				// シリアル番号
		
		if (!empty($act)) return $serial;		// 初期呼び出し時以外は終了
		
		$value = $request->trimValueOf(M3_REQUEST_PARAM_PAGE_DEF_SERIAL);
		if ($value != '') $serial = intval($value);
		if ($serial < 0) $serial = 0;		// エラー値を修正
		return $serial;
	}
	/**
	 * ウィジェットの呼び出しが可能か取得
	 *
	 * @param string $widgetId		呼び出し対象のウィジェット
	 * @return bool					true=呼び出し可能、false=呼び出し不可
	 */
	function canFindWidget($widgetId)
	{
		$ret = $this->gPage->isWidgetOnPage($this->gEnv->getCurrentPageId(), $widgetId);
		return $ret;
	}
	/**
	 * 自ウィジェットの管理画面用のURLを作成
	 *
	 * @param string,array $param		URLに付加するパラメータ
	 * @return string					作成したURL
	 */
	function getConfigAdminUrl($param = '')
	{
		// パラメータを作成
		$paramArray = array();
		$paramArray[M3_REQUEST_PARAM_OPERATION_COMMAND] = M3_REQUEST_CMD_CONFIG_WIDGET;			// ウィジェット定義
		$paramArray[M3_REQUEST_PARAM_WIDGET_ID] = $this->gEnv->getCurrentWidgetId();			// ウィジェットID
		if (is_array($param)){
			$paramArray = array_merge($paramArray, $param);
		} else if (is_string($param) && !empty($param)){
			parse_str($param, $addArray);
			$paramArray = array_merge($paramArray, $addArray);
		}
		
		// URL作成
		$destUrl = $this->gEnv->getDefaultAdminUrl();
		$paramStr = $this->_createParamStr($paramArray);
		if (!empty($paramStr)) $destUrl .= '?' . $paramStr;
		return $destUrl;
	}
	/**
	 * URLを作成
	 *
	 * ・ページのSSL設定状況に応じて、SSL用URLに変換
	 *
	 * @param string $path				URL作成用のパス
	 * @param bool $isLink				作成するURLがリンクかどうか。リンクの場合はリンク先のページのSSLの状態に合わせる
	 * @param string,array $param		URLに付加するパラメータ
	 * @return string					作成したURL
	 */
	function getUrl($path, $isLink = false, $param = '')
	{
		$destPath = '';
		$path = trim($path);
		
		// URLの示すファイルタイプを取得
		if ($this->gEnv->getUseSsl()){		// SSLを使用する場合
			// 現在のページがSSL使用設定になっているかどうかを取得
			$isSslPage = $this->gPage->isSslPage($this->gEnv->getCurrentPageId(), $this->gEnv->getCurrentPageSubId());
			
			$baseUrl = $this->gEnv->getRootUrl();
			$sslBaseUrl = $this->gEnv->getSslRootUrl();		// SSL用URLが設定されている場合、設定値を使用
			
			// パスを解析
			if (strStartsWith($path, M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END)){		// Magic3のルートURLマクロのとき
				$relativePath = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, '', $path);
				if (empty($relativePath)){			// Magic3のルートURLの場合
					// 現在のページのSSLの状態に合わせる
					if ($isSslPage){
						$destPath = $sslBaseUrl;
					} else {
						$destPath = $baseUrl;
					}
					// トップページへのリンクの場合とどう区別するか→トップページへのリンクの場合はフルパスで指定?
				} else {
					$destPath = self::_createUrlByRelativePath($isSslPage, $baseUrl, $sslBaseUrl, $relativePath, $param, $isLink);
				}
			} else if (strncasecmp($path, 'http://', strlen('http://')) == 0 || strncasecmp($path, 'https://', strlen('https://')) == 0){				// 絶対パスURLのとき
				// パスを解析
				$relativePath = str_replace($baseUrl, '', $path);		// ルートURLからの相対パスを取得
				if (empty($relativePath)){			// Magic3のルートURLの場合
					// 現在のページのSSLの状態に合わせる
					if ($isSslPage){
						$destPath = $sslBaseUrl;
					} else {
						$destPath = $baseUrl;
					}
					// トップページへのリンクの場合とどう区別するか→トップページへのリンクの場合はフルパスで指定?
				} else if (strStartsWith($relativePath, '/') || strStartsWith($relativePath, '?')){		// ルートURL配下のとき
					$destPath = self::_createUrlByRelativePath($isSslPage, $baseUrl, $sslBaseUrl, $relativePath, $param, $isLink);
				} else {		// ルートURL以外のURLのとき
					$destPath = $path;
				}
			} else {		// 相対パスのとき
			}
		} else {
			if (strStartsWith($path, M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END)){		// Magic3のルートURLマクロのとき
				$destPath = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $path);
			} else {
				$destPath = $path;
			}
		}
		return $destPath;
	}
	/**
	 * 相対パスからURLを作成
	 *
	 * @param bool $isSslPage		現在のページがSSL使用になっているかどうか
	 * @param string $baseUrl		ルートURL
	 * @param string $sslBaseUrl	SSL使用時のルートURL
	 * @param string $path			相対パス
	 * @param string,array $param		URLに付加するパラメータ
	 * @param bool $isLink				作成するURLがリンクかどうか。リンクの場合はリンク先のページのSSLの状態に合わせる
	 * @return string				作成したURLパラメータ
	 */
	function _createUrlByRelativePath($isSslPage, $baseUrl, $sslBaseUrl, $path, $param = '', $isLink = false)
	{
		$destPath = '';
		
		// ファイル名を取得
		$paramArray = array();
		list($filename, $query) = explode('?', basename($path));
		$saveFilename = $filename;		// ファイル名を退避
		if (empty($filename)) $filename = M3_FILENAME_INDEX;

		if (!empty($query)) parse_str($query, $paramArray);
		if (is_array($param)){
			$paramArray = array_merge($paramArray, $param);
		} else if (is_string($param) && !empty($param)){
			parse_str($param, $addArray);
			$paramArray = array_merge($paramArray, $addArray);
		}
		// ページIDを取得
		if (strEndsWith($filename, '.php')){			// PHPスクリプトのとき
			if ($isLink){		// リンクタイプのとき
				// ページIDを取得
				$pageId = basename($filename, '.php');
				$pageSubId = $paramArray['sub'];
			
				// 目的のページのSSL設定状況を取得
				$isSslSelPage = $this->gPage->isSslPage($pageId, $pageSubId);
				if ($isSslSelPage){
					$destPath = $sslBaseUrl;
				} else {
					$destPath = $baseUrl;
				}
			} else {
				// 現在のページのSSLの状態に合わせる
				if ($isSslPage){
					$destPath = $sslBaseUrl . $path;
				} else {
					$destPath = $baseUrl . $path;
				}
			}
			$dirName = dirname($path);
			if ($dirName == '/'){
				$destPath .= $dirName . $saveFilename;
			} else {
				$destPath .= $dirName . '/' . $saveFilename;
			}
			// ページサブIDがデフォルト値のときはページサブIDを省略
			//if ($paramArray['sub'] == 
			$paramStr = $this->_createParamStr($paramArray);
			if (!empty($paramStr)) $destPath .= '?' . $paramStr;
		} else {
			// 現在のページのSSLの状態に合わせる
			if ($isSslPage){
				$destPath = $sslBaseUrl . $path;
			} else {
				$destPath = $baseUrl . $path;
			}
		}
		return $destPath;
	}
	/**
	 * URLパラメータ文字列作成
	 *
	 * @param array $paramArray			URL作成用のパス
	 * @return string					作成したURLパラメータ
	 */
	function _createParamStr($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;
	}
	/**
	 * キャッシュデータをクリア
	 *
	 * @param array $param	削除する対象のURLパラメータ。空のときはすべてのデータを削除。
	 * @return 				なし
	 */
	function clearCache($param = array())
	{
		$this->gCache->clearCacheByWidgetId($this->gEnv->getCurrentWidgetId(), $param);
	}
}
?>
