<?php
/*
 * system/login/ModuleBase.class.php
 * 
 * CopyRight(C) 2010 Shopformer Development Team. All Right Reserved
 * URL: http://sourceforge.jp/projects/shopformer/
 * 
 * 
 * Mail: m_nakashima@users.sourceforge.jp
 * Auther: Masanori Nakashima
 * Last Update: 2010-06-18
 */
require_once( dirname(dirname(__FILE__))
.DIRECTORY_SEPARATOR.'PackageConfig.class.php');
require_once( dirname(dirname(dirname(__FILE__)))
.DIRECTORY_SEPARATOR.'spider'
.DIRECTORY_SEPARATOR.'ModuleBase.class.php');
require_once( dirname(__FILE__)
.DIRECTORY_SEPARATOR.'UserAdministrator.class.php' );
require_once( dirname(__FILE__)
.DIRECTORY_SEPARATOR.'UserGuest.class.php' );
/**
 * spider : ログイン要求用アクションモジュール基底クラス
 * 
 * 本モジュールをページ側でコールすると、該当するページ及びディレクトリ内で
 * ログイン必須となります。
 * 
 * @package system
 * @subpackage login
 * @category module
 * @version 1.2.00
 * @copyright Copyright(c)2011, Shopformer Development Team. <shopformer-dev@lists.sourceforge.jp>
 * @author Masanori Nakashima
 * @access public
 */
class system_login_ModuleBase extends spider_ModuleBase {
	var $systemPackageConfig	= null;
	function system_login_ModuleBase(){
	}
	function execute( & $request ) {
	}
	/**
	 * ログインしているか確認します
	 * ログインされていないまたはエラーが発生している場合はfalseを返します
	 * @param $request spider_HttpRequestオブジェクト
	 * @return mixed
	 */
	function isLogin( & $request ) {
		$userClassName	= $request->getSession(SYSTEM_SESSION_NAME_LOGIN_CLASS_NAME);
		if( !is_null($userClassName) ) {
			// ユーザー定義クラスの読み込み
			if( !class_exists($userClassName) ) {
				if( system_PackageConfig::loadUserClassFile( $request, $userClassName ) ) {
				} else {
					return false;
				}
			}
			// ログインユーザー情報をセッションから取得
			if( !$request->existsSession(SYSTEM_SESSION_NAME_LOGIN_INFORMATION) ) {
				// ログインされていない
				return false;
			} else {
				$loginInformationObject	= $request->getSession(SYSTEM_SESSION_NAME_LOGIN_INFORMATION);
				if( is_a($loginInformationObject,'system_login_AbstractUser')
					&& 'system_login_userguest' != strtolower(get_class($loginInformationObject)) ) {
					// ユーザークラスの実装として定義されていてゲストでない場合
					if( defined('SPIDER_USE_SPIDER_SESSION_ID') && SPIDER_USE_SPIDER_SESSION_ID !== false ) {
						// spiderセッションを利用している場合リモートホストとユーザーエージェントチェック済みなのでOK
						return true;
					} else {
						// spiderセッションを利用していない場合はリモートホストとユーザーエージェントチェック
						$remoteHost		= spider_HttpRequest::getRemoteHostString();
						$agentClass		= $request->agentClass;
						$permitHostArray	= array();
						if( isset($GLOBALS['SPIDER_USER_AGENT_REMOTE_SESSION_PERMIT_HOSTS'][$agentClass]) ) {
							$permitHostArray	= $GLOBALS['SPIDER_USER_AGENT_REMOTE_SESSION_PERMIT_HOSTS'][$agentClass];
						}
						if( is_array($permitHostArray) && count($permitHostArray) > 0 ) {
							// セッション維持リモートホスト名の正規表現が指定されている場合
							// 前回アクセスのリモートホストに関係なく配列要素にマッチがあればOK
							foreach( $permitHostArray as $hostRegx ) {
								if( preg_match($hostRegx,$remoteHost) > 0 ) {
									return true;
								}
							}
							return false;
						} else {
							// セッション維持リモートホストが指定されていないケースの場合
							$sessionRemoteHost	= '';
							if( isset($_SESSION['system.login.remoteHost']) > 0 ) {
								$sessionRemoteHost	= unserialize($_SESSION['system.login.remoteHost']);
								// 前回のアクセスと一致を要求
								if( $remoteHost != $sessionRemoteHost ) {
									return false;
								} else {
									return true;
								}
							} else {
								// 初回アクセスならセッションに登録してＯＫ
								$_SESSION['system.login.remoteHost']	= serialize(spider_HttpRequest::getRemoteHostString());
								return true;
							}
						}
					}
				} else {
					return false;
				}
			}
		} else {
			return false;
		}
	}
	/**
	 * ログインユーザー情報オブジェクトを取得します
	 * ログインされていない場合はsystem_login_UserGuestオブジェクトを返します
	 * システムエラーの場合はfalseを返します。
	 * @param $request spider_HttpRequestオブジェクト
	 * @return mixed
	 */
	function getLoginUserObject( & $request ) {
		if( system_login_ModuleBase::isLogin( $request ) ) {
			return $request->getSession(SYSTEM_SESSION_NAME_LOGIN_INFORMATION);
		} else {
			// ログインしていない場合固定でsystem_login_UserGuestオブジェクトを返す
			return new system_login_UserGuest();
		}
	}
	/**
	 * ログインユーザー情報オブジェクトを設定します
	 * システムエラーの場合はfalseを返します。
	 * @param $request spider_HttpRequestオブジェクト
	 * @return mixed
	 */
	function setLoginUserObject( & $request, $loginInformationObject ) {
		if( is_a($loginInformationObject,'system_login_AbstractUser')
			&& !is_a($loginInformationObject,'system_login_UserGuest') ) {
			$request->setSession(SYSTEM_SESSION_NAME_LOGIN_INFORMATION, $loginInformationObject, SPIDER_SESSION_SCOPE_GLOBAL);
			$request->setSession( SYSTEM_SESSION_NAME_LOGIN_CLASS_NAME, get_class($loginInformationObject), SPIDER_SESSION_SCOPE_GLOBAL );
			return true;
		}
		return false;
	}
	/**
	 * 指定ページファイルにリダイレクトします
	 */
	function pageRedirect( & $request, $pageFile ) {
		$targetFolderUri	= dirname(SPIDER_URI_APP).'/';
		$redirectUri		= null;
		$targetFileUri		= null;
		while( strlen($targetFolderUri) > 0 ) {
			$targetFileUri	= $targetFolderUri.$pageFile;
			if( system_DataFileWriter::isExists($request,$targetFileUri,'public')
				&& $targetFileUri != SPIDER_URI_APP ) {
				break;
			} else if( DIRECTORY_SEPARATOR == $targetFolderUri ) {
				break;
			} else {
				$targetFileUri	= null;
				if( DIRECTORY_SEPARATOR == dirname($targetFolderUri) ) {
					$targetFolderUri	= '/';
				} else {
					$targetFolderUri	= dirname($targetFolderUri).'/';
				}
			}
		}
		if( is_null($targetFileUri) ) {
			// 指定名のファイルが見つからなかった場合
			if( $request->existsSession(SYSTEM_SESSION_NAME_LOGIN_BASE_URI) ) {
				// セッションにログインベースがあるなら
				$loginBaseUri	= $request->getSession(SYSTEM_SESSION_NAME_LOGIN_BASE_URI);
				if( preg_match('/\\/$/',$loginBaseUri) == 0 ) {
					$loginBaseUri	.= '/';
				}
				// ログインベースURIにターゲットファイルがあるか確認
				$targetFileUri	= $loginBaseUri.$pageFile;
				if( system_DataFileWriter::isExists($request,$targetFileUri,'public') ) {
					$redirectUri	= $targetFileUri;
				} else {
					$redirectUri	= $loginBaseUri;
					if( SPIDER_PHP_SELF == $loginBaseUri.'index.php' ) {
						// ログインベースがリダイレクトを発生させようとしているページと同一ならアプリケーションベース
						$redirectUri	= SPIDER_URI_BASE;
					}
				}
			} else {
				$redirectUri	= SPIDER_URI_BASE;
			}
		} else {
			// アプリケーション内URIから設置絶対URIに変換
			$targetFileUri	= str_replace('//','/',SPIDER_URI_BASE.$targetFileUri);
			$redirectUri	= $targetFileUri;
		}
		$redirectUri	= str_replace('//','/',$redirectUri);
		$request->setResponseHeader( 'Expires', 'Mon, 26 Jul 1997 05:00:00 GMT' );
		$request->setResponseHeader( 'Cache-Control', 'no-store, no-cache, must-revalidate' );
		$request->setResponseHeader( 'Cache-Control', 'pre-check=0, post-check=0, max-age=0' );
		$request->setResponseHeader( 'Pragma', 'no-cache' );
		$request->setResponseHeader( 'Expires', '0' );
		$request->redirectTo($redirectUri);
	}
	/**
	 * 渡されたAbstractData実装オブジェクトに対して編集ロックを取得します。
	 * @param &$request spider_HttpRequestオブジェクト参照
	 * @param $abstractData system_AbstractData実装オブジェクト
	 * @param $lifeTime ロックの有効秒数
	 * @return ロックを取得出来たらtrue
	 */
	function lockData( & $request, $abstractData, $lifeTime=300 ) {
		$userObject	= $this->getLoginUserObject( $request );
		return $userObject->lockData( $request, $abstractData, $lifeTime );
	}
	/**
	 * 渡されたAbstractDataオブジェクトに対して編集ロックを解除します。
	 * @param &$request spider_HttpRequestオブジェクト参照
	 * @param $abstractData system_AbstractData実装オブジェクト
	 * @return ロックを解除出来たらtrue
	 */
	function unlockData( & $request, $abstractData ) {
		$userObject	= $this->getLoginUserObject( $request );
		return $userObject->unlockData( $request, $abstractData );
	}
	/**
	 * 渡されたAbstractDataオブジェクトに対して編集ロックを取得可能か確認します。
	 * @param &$request spider_HttpRequestオブジェクト参照
	 * @param $abstractData system_AbstractData実装オブジェクト
	 * @return ロックを取得できるならtrue/取得できないならfalse
	 */
	function canLockData( & $request, $abstractData ) {
		$userObject	= $this->getLoginUserObject( $request );
		return $userObject->canLockData( $request, $abstractData );
	}
	/**
	 * 渡されたAbstractDataオブジェクトに対して現在のロック状態をメンバとして設定します。
	 * ->is_lock = true/false
	 * ->is_editable = true/false
	 * @param &$request spider_HttpRequestオブジェクト参照
	 * @param $abstractData system_AbstractData実装オブジェクト
	 */
	function setLockStatus( & $request, & $abstractData ) {
		$userObject	= $this->getLoginUserObject( $request );
		if( $abstractData->isLock() ) {
			$abstractData->is_lock		= true;
			if( $userObject->canLockData( $request, $abstractData ) ) {
				$abstractData->is_editable	= true;
			} else {
				$abstractData->is_editable	= false;
			}
		} else {
			$abstractData->is_lock		= false;
			$abstractData->is_editable	= true;
		}
	}
	//
	// 
	//
	/**
	 * 指定されたログインIDがシステム上に存在するか確認します
	 * @param $request spider_HttpRequestオブジェクト
	 * @param $loginId ログインID
	 * @return 存在するならtrue / 存在しないかエラーが発生した場合にはfalse
	 */
	function isExistLoginId( & $request, $loginId ){
		if( is_null( $this->systemPackageConfig ) ) {
			$this->systemPackageConfig	= new system_PackageConfig();
			$this->systemPackageConfig->load($request);
		}
		return $this->systemPackageConfig->isExistLoginId( $request, $loginId );
	}
	/**
	 * 指定されたユーザユニークIDがシステム上に存在するか確認します
	 * @param $request spider_HttpRequestオブジェクト
	 * @param $uniqueId ログインID
	 * @return 存在するならtrue / 存在しないかエラーが発生した場合にはfalse
	 */
	function isExistUniqueId( & $request, $uniqueId ){
		if( is_null( $this->systemPackageConfig ) ) {
			$this->systemPackageConfig	= new system_PackageConfig();
			$this->systemPackageConfig->load($request);
		}
		return $this->systemPackageConfig->isExistUniqueId( $request, $uniqueId );
	}
	/**
	 * 指定ログインIDのユーザーオブジェクトを取得します
	 * @param $request spider_HttpRequestオブジェクト
	 * @param $loginId ログインID
	 */
	function getUserObjectByLoginId( & $request, $loginId ) {
		if( is_null( $this->systemPackageConfig ) ) {
			$this->systemPackageConfig	= new system_PackageConfig();
			$this->systemPackageConfig->load($request);
		}
		return $this->systemPackageConfig->getUserObjectByLoginId( $request, $loginId );
	}
	/**
	 * 指定されたユーザユニークIDユーザーオブジェクトを取得します
	 * @param $request spider_HttpRequestオブジェクト
	 * @param $uniqueId ログインID
	 * @return 存在するならユーザーオブジェクト / 存在しないかエラーが発生した場合にはfalse
	 */
	function getUserObjectByUniqueId( & $request, $uniqueId ) {
		if( is_null( $this->systemPackageConfig ) ) {
			$this->systemPackageConfig	= new system_PackageConfig();
			$this->systemPackageConfig->load($request);
		}
		return $this->systemPackageConfig->getUserObjectByUniqueId( $request, $uniqueId );
	}
}
?>