<?php
/*
 * system/package/install/Form.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(dirname(__FILE__)))
.DIRECTORY_SEPARATOR.'PackageConfig.class.php');
/**
 * spider : systemパッケージ/パッケージインストーラ 入力フォーム表示用アクションモジュールクラス
 * 
 * spiderのページから呼び出して実行します。
 * 
 * @package system
 * @subpackage package
 * @category module
 * @version 1.2.00
 * @copyright Copyright(c)2011, Shopformer Development Team. <shopformer-dev@lists.sourceforge.jp>
 * @author Masanori Nakashima
 * @access public
 * @abstract
 */
class system_package_install_Form extends system_login_ModuleBase {
	
	function system_package_install_Form(){
		// インストール済みパッケージ読み込みモジュールを先に実行
		array_push($this->require_module_array,'system.package.LoadList');
	}
	function execute( & $request ) {
		$targetPackageId	= $request->getParam('sitpi','get');
		$command			= $request->getParam('cmd','get');
		if( is_null($targetPackageId) || strlen($targetPackageId) == 0 ) {
			$targetPackageId	= 'system';
		}
		// インストール済みパッケージID配列
		$installedPackageIdArray	= $request->getAttribute('system.package.installedPackageIdArray');
		$request->removeSession(SYSTEM_SESSION_NAME_PACKAGE_INSTALL_CONFIRM_RESULT,SPIDER_SESSION_SCOPE_GLOBAL);
		if( preg_match('/^[nN][eE][wW]$/',$command) > 0 ) {
			$request->removeSession(SYSTEM_SESSION_NAME_PACKAGE_INSTALL_OBJECT_HASH,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SYSTEM_SESSION_NAME_PACKAGE_INSTALL_CONFIRM_RESULT,SPIDER_SESSION_SCOPE_GLOBAL);
			$redirectUri	= preg_replace( '/\\?cmd\\=[nN][eE][wW]/','?', SPIDER_URI_REQUEST );
			$redirectUri	= preg_replace( '/\\&cmd\\=[nN][eE][wW]/','', $redirectUri );
			$request->redirectTo( $redirectUri );
		} else {
			// インストールするパッケージIDの配列
			$installPackageIdArray					= null;
			// インストールするパッケージオブジェクトのハッシュ
			$installPackageConfigObjectHash		= null;
			if( $request->existsSession(SYSTEM_SESSION_NAME_PACKAGE_INSTALL_OBJECT_HASH) ) {
				// セッションに登録されているなら
				$installPackageConfigObjectHash	= $request->getSession(SYSTEM_SESSION_NAME_PACKAGE_INSTALL_OBJECT_HASH,SPIDER_SESSION_SCOPE_GLOBAL);
				// 対象パッケージID配列の初期化
				$installPackageIdArray				= array();
				foreach( $installPackageConfigObjectHash as $packageId => $packageConfigObject ) {
					array_push( $installPackageIdArray, $packageId );
				}
				$targetPackageConfigObject		= $installPackageConfigObjectHash[$targetPackageId];
				if( is_array($installPackageConfigObjectHash) ) {
					// 要求IDの配列を初期化
					$installPackageIdArray		= array();
					// セッションに確認済みオブジェクト配列があるならID配列を作成する
					foreach( $installPackageConfigObjectHash as $installPackageObject ) {
						array_push( $installPackageIdArray, $installPackageObject->getPackageId() );
					}
				}
			} else {
				if( strlen(trim($targetPackageId)) == 0 ) {
					$request->addLocaledError('system.error.package.nopackage',SPIDER_LOG_LEVEL_ERROR,array());
				} else {
					// 対象のパッケージ情報クラスを取得
					$targetPackageConfigObject		= system_package_install_Form::getPackageConfigInstance( $request, $targetPackageId );
					if( $targetPackageConfigObject ) {
						// 要求IDの配列を初期化
						$installPackageIdArray		= array();
						// 要求パッケージオブジェクト配列の初期化
						$installPackageConfigObjectHash	= array();
						// 要求パッケージIDの優先順配列を取得
						$installPackageIdArray		= system_package_install_Form::createRequiredPackageIdArray( $request, $targetPackageId, $installPackageIdArray );
						if( is_array($installPackageIdArray) && count($installPackageIdArray) > 0 ) {
							foreach( $installPackageIdArray as $requiredPackageId ) {
								$requiredPackageObject	= system_package_install_Form::getPackageConfigInstance( $request, $requiredPackageId );
								if( $requiredPackageObject ) {
									$installPackageConfigObjectHash[$requiredPackageObject->getPackageId()]	= $requiredPackageObject;
								}
							}
						} else {
							$installPackageConfigObjectHash[$targetPackageConfigObject->getPackageId()]	= $targetPackageConfigObject;
							array_push( $installPackageIdArray , $targetPackageConfigObject->getPackageId());
						}
					} else {
						$installPackageConfigObjectHash	= array();
						$installPackageIdArray			= array();
					}
				}
			}
			$request->setSession(SYSTEM_SESSION_NAME_PACKAGE_INSTALL_OBJECT_HASH,$installPackageConfigObjectHash,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->setAttribute('system.package.install.target_package_object',$targetPackageConfigObject);
			$request->setAttribute('system.package.install.install_id_array',$installPackageIdArray);
			$request->setAttribute('system.package.install.install_object_hash',$installPackageConfigObjectHash);
		}
	}
	/**
	 * パッケージIDからパッケージを実体化して返します。
	 */
	function getPackageConfigInstance( & $request, $packageId ) {
		if( system_package_install_Form::requireInstallPackageConfigFile( $request, $packageId ) ) {
			$packageConfigClassName	= $packageId.'_PackageConfig';
			if( class_exists($packageConfigClassName) ) {
				// パッケージオブジェクトの作成
				$packageConfigObject	= new $packageConfigClassName;
				$packageConfigObject->load( $request );
				return $packageConfigObject;
			} else {
				$request->addLocaledError('system.error.package.nodefinedpackage',SPIDER_LOG_LEVEL_ERROR,array($packageId));
				return false;
			}
		} else {
			return false;
		}
	}
	/**
	 * パッケージIDから必要なPackageConfig.class.phpファイルをrequireします
	 */
	function requireInstallPackageConfigFile( & $request, $packageId ) {
		$packageConfigClassFile	= DIR_PATH_LIB.DIRECTORY_SEPARATOR.$packageId
			. DIRECTORY_SEPARATOR.'PackageConfig.class.php';
		if( !file_exists( $packageConfigClassFile ) ) {
			$request->addLocaledError('system.error.package.nodefinedpackage',SPIDER_LOG_LEVEL_ERROR,array($packageId));
			return false;
		} else if( !@require_once( $packageConfigClassFile ) ) {
			$request->addLocaledError('system.error.package.failtoinstant',SPIDER_LOG_LEVEL_ERROR,array($packageId));
			return false;
		} else {
			return true;
		}
	}
	/**
	 * 指定パッケージに対する要求パッケージIDの優先順配列を取得します
	 */
	function createRequiredPackageIdArray( & $request, $targetPackageId, $requiredPackageIdArray ) {
		// インストール済みパッケージID配列
		$installedPackageIdArray	= $request->getAttribute('system.package.installedPackageIdArray');
		// リターンするパッケージIDの配列
		$returnPackageIdArray	= array();
		// 指定パッケージのオブジェクト取得
		$installPackageObject			= system_package_install_Form::getPackageConfigInstance( $request, $targetPackageId );
		if( $installPackageObject ) {
			// ターゲットが要求するパッケージIDの配列を作成
			$dependentPackageIdArray	= $installPackageObject->getPackageDependenciesIdArray();
			if( is_array( $dependentPackageIdArray ) ) {
				foreach( $dependentPackageIdArray as $requiredPackageId ) {
					if( !in_array( $requiredPackageId, $installedPackageIdArray ) ) {
						array_push( $returnPackageIdArray, $requiredPackageId );
						$returnPackageIdArray	= system_package_install_Form::createRequiredPackageIdArray( $request, $requiredPackageId, $returnPackageIdArray );
					}
				}
			}
			// ターゲットのパッケージIDを追加
			if( !in_array( $targetPackageId, $installedPackageIdArray ) ) {
				array_push( $returnPackageIdArray, $targetPackageId );
			}
			// 今までのパッケージで要求されていたパッケージIDを後に追加する
			$return_id_array	= array();
			foreach( $requiredPackageIdArray as $requiredPackageId ) {
				if( is_array( $returnPackageIdArray ) ) {
					// 要求パッケージ配列がある場合あるなら追加しない
					if( !in_array( $requiredPackageId, $returnPackageIdArray )
						&& !in_array( $requiredPackageId, $installedPackageIdArray ) ) {
						array_push( $returnPackageIdArray, $requiredPackageId );
					}
				} else {
					if( !in_array( $requiredPackageId, $installedPackageIdArray ) ) {
						array_push( $returnPackageIdArray, $requiredPackageId );
					}
				}
			}
			return $returnPackageIdArray;
		} else {
			$request->addLocaledError('system.error.package.failtodepandencies',SPIDER_LOG_LEVEL_ERROR,array());
			return false;
		}
	}
}
?>