<?php
/*
 * system/tools/update/Execute.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-30
 */
require_once(dirname(dirname(dirname(__FILE__)))
.DIRECTORY_SEPARATOR.'PackageConfig.class.php');
/**
 * spider : 
 * 
 * @package system
 * @subpackage tools
 * @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_tools_update_Execute extends system_login_ModuleBase {
	function system_tools_update_Execute(){
	}
	function execute( & $request ) {

		$productName	= trim(stripslashes( $_POST['product'] ));
		$versionName	= trim(stripslashes( $_POST['version'] ));
		$targetFile		= trim(stripslashes( $_POST['targetFile'] ));
		
		if( strlen($productName) == 0 ) {
			$productName	= RELEASE_NAME;
		}
		if( preg_match('/^[0-9]\\.[0-9]\\.[0-9][0-9]$/',$versionName) == 0 ) {
			$request->addLocaledError('system.error.tools.update.invalidversion',SPIDER_LOG_LEVEL_ERROR,array($versionName));
		}
		if( strlen($targetFile) == 0 ) {
			$request->addLocaledError('system.error.tools.update.filenamerequired',SPIDER_LOG_LEVEL_ERROR,array($versionName));
		}
		// システムチェック
		$selfFileTarget	= null;
		$selfFileUri	= null;
		$selfFilePath	= null;
		if( !$request->isError() ) {
			if( preg_match('/^panel\\//',$targetFile) > 0 ) {
				// 管理パネル内のアップデート
				$selfFileTarget	= 'public';
				$selfFileUri	= str_replace('//','/','/'.preg_replace('/^panel/',SYSTEM_DIR_NAME_ADMIN_PANEL,$targetFile));
				$selfFilePath	= str_replace('//','/',SPIDER_BASE_PATH.$selfFileUri);
			} else if( preg_match('/^spider\\//',$targetFile) > 0 ) {
				// spiderフォルダ内のアップデート
				$selfFileTarget	= 'spider';
				$selfFileUri	= preg_replace('/^spider/','',$targetFile);
				$selfFilePath	= str_replace('//','/',DIR_PATH_SPIDER.$selfFileUri);
			} else {
				// 公開
				$selfFileTarget	= 'public';
				$selfFileUri	= str_replace('//','/','/'.$targetFile);
				$selfFilePath	= str_replace('//','/',SPIDER_BASE_PATH.$selfFileUri);
			}
			// 権限の確認
			if( file_exists($selfFilePath) ) {
				// 既に存在するファイルの場合
				if( !is_writable($selfFilePath) ) {
					// 書き込み権限がなければエラー
					$request->addLocaledError('system.error.writer.save',SPIDER_LOG_LEVEL_ERROR,array($selfFilePath));
				}
			} else {
				// 存在しないファイルの場合格納フォルダをチェック
				$selfFolderPath	= dirname($selfFilePath);
				while( !file_exists($selfFolderPath) ) {
					$selfFolderPath	= dirname($selfFolderPath);
				}
				if( !is_writable($selfFolderPath) ) {
					$request->addLocaledError('system.error.writer.save',SPIDER_LOG_LEVEL_ERROR,array($selfFolderPath));
				}
			}
		}
		// SVN接続
		if( !$request->isError() ) {
			$svnUrl	= SYSTEM_UPDATE_SVN_URL.$productName.'/'.$versionName.'/'.$productName.'/'.$targetFile;
			$headerParms	= array();
			$headerParms['Authorization']	= 'Basic '.base64_encode(SYSTEM_UPDATE_SVN_ID.':'.SYSTEM_UPDATE_SVN_PW);
			spider_Controller::loadClassDefinition('util_HttpRequest');
			$httpRequest	= new util_HttpRequest($svnUrl,'get',$headerParms);
			// HTTPリクエスト実行
			if( $httpRequest->send(null,60) ) {
				// 通信成功の場合
				if( '200' == $httpRequest->statusCode ) {
					// 200の場合ファイルを上書き保存
					$writer	= new system_DataFileWriter();
					if( $writer->open( $request, $selfFileUri, 'w', $selfFileTarget ) ) {
						$writer->write( $httpRequest->responseBody );
						$writer->close( $request );
					}
					if( 'spider' == $selfFileTarget && '/unique_setting.format.txt' == $selfFileUri ) {
						// unique_settingフォーマットが更新されている場合マイグレーション
						$this->mygrateUniqueSetting( $request );
					} else if( 'spider' == $selfFileTarget && preg_match('/^\\/application\\.update(|\\.[0-9]{1,2})\\.php$/',$selfFileUri) > 0 ) {
						// update.phpで正常に取得できているなら実行して削除
						$filePath	= realpath(DIR_PATH_SPIDER.$selfFileUri);
						if( file_exists($filePath) ) {
							include_once($filePath);
							system_DataFileWriter::delete( $request, $selfFileUri, 'spider' );
						}
					}
					// ターゲットファイルがspiderの構成ファイルならbin内を削除
					if( preg_match('/spider\\/lib\\/spider/',$targetFile) > 0 ) {
						system_DataFileWriter::deleteDir( $request, '/'.DIR_NAME_WORK.'/'.DIR_NAME_BIN, 'spider' );
					}
				} else {
					$request->addLocaledError('system.error.tools.update.httprequest',SPIDER_LOG_LEVEL_ERROR,array($httpRequest->statusCode,$httpRequest->statusMessage));
				}
			} else {
				// 通信失敗の場合
					$request->addLocaledError('system.error.tools.update.httprequest',SPIDER_LOG_LEVEL_ERROR,array($httpRequest->statusCode,$httpRequest->statusMessage));
			}
		}
	}
	/**
	 * unique_setting.inc.phpのマイグレーションを実行します
	 */
	function mygrateUniqueSetting( & $request ) {
		$formatPath	= DIR_PATH_SPIDER.DIRECTORY_SEPARATOR.'unique_setting.format.txt';
		if( file_exists($formatPath) ) {
			$formatBody	= file_get_contents($formatPath);
			// 定義文字列の置き換え
			foreach( $GLOBALS['APP_REPLACE_DEF_NAME_ARRAY'] as $defName => $defaultVal ) {
				$repTarget	= '{write:'.$defName.'}';
				$repValue	= null;
				$repString	= '';
				// 置換値
				if( defined($defName) ) {
					// defineで定義されているなら文字列を置換（配列はない）
					$repValue	= constant($defName);
				} else if( isset($GLOBALS[$defName]) && is_array($GLOBALS[$defName]) ) {
					// グローバル変数の配列なら
					$repValue	= $GLOBALS[$defName];
				} else {
					// 定数にもグローバル配列にもないならデフォルト値
					$repValue	= $GLOBALS['APP_REPLACE_DEF_NAME_ARRAY'][$defName];
				}
				// 値を文字列定義に置き換え
				if( is_array($repValue) ) {
					// 配列の場合
					$repString	= "array(\n";
					foreach( $GLOBALS[$defName] as $k => $val ) {
						$outKey	= $k;
						$outVal	= $val;
						if( preg_match('/^[0-9]{1,7}$/',$k) ) {
						} else {
							$outKey	= str_replace("\r\n","\n",str_replace("\r","\n",$outKey));
							$outKey	= str_replace("\n","\\n",$outKey);
							$outKey	= str_replace("\t","\\t",$outKey);
							$outKey	= str_replace('"','\\"',$outKey);
							$outKey	= '"'.$outKey.'"';
						}
						if( preg_match('/^[0-9]{1,7}$/',$val) ) {
						} else {
							$outVal	= str_replace("\r\n","\n",str_replace("\r","\n",$outVal));
							$outVal	= str_replace("\n","\\n",$outVal);
							$outVal	= str_replace("\t","\\t",$outVal);
							$outVal	= str_replace('"','\\"',$outVal);
							$outVal	= '"'.$outVal.'"';
						}
						if( array_keys($GLOBALS[$defName]) === range(0, count($GLOBALS[$defName]) - 1) ) {
							// 配列
							$repString	.= "\t".$outVal.",\n";
						} else {
							// 連想配列
							$repString	.= "\t".$outKey." => ".$outVal.",\n";
						}
					}
					$repString	.= ")";
				} else {
					// 文字列の場合
					if( preg_match('/^[0-9]{1,7}$/',$repValue) ) {
						// 数値の場合デフォルト値の書式によって出力表記を変更する
						if( preg_match('/^0x/',$GLOBALS['APP_REPLACE_DEF_NAME_ARRAY'][$defName]) > 0 ) {
							// 16進数表記
							$repString	= '0x'.sprintf('%x',$repValue);
						} else if( preg_match('/^0/',$GLOBALS['APP_REPLACE_DEF_NAME_ARRAY'][$defName]) > 0 ) {
							// 8進数表記
							$repString	= '0'.sprintf('%o',$repValue);
						} else {
							// 10進数
							$repString	= $repValue;
						}
					} else {
						// 文字列の場合はクォート
						$repString	= str_replace("\r\n","\n",str_replace("\r","\n",$repValue));
						$repString	= str_replace("\n","\\n",$repString);
						$repString	= str_replace("\t","\\t",$repString);
						$repString	= str_replace('"','\\"',$repString);
						$repString	= '"'.$repString.'"';
					}
				}
				$formatBody	= str_replace($repTarget,$repString,$formatBody);
			}
			// unique_setting.inc.phpの書き換えを試み
			$writer	= new system_DataFileWriter();
			if( $writer->open( $request, '/unique_setting.inc.php', 'w', 'spider' ) ) {
				$writer->write( $formatBody );
				$writer->close( $request );
			}
		}
	}
}
?>