<?php
/*
 * shopping/order/file/Upload.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-12-16
 */
require_once(dirname(dirname(dirname(__FILE__)))
.DIRECTORY_SEPARATOR.'PackageConfig.class.php' );
class shopping_order_file_Upload extends system_login_ModuleBase {
	function shopping_order_file_Upload(){
		array_push( $this->require_module_array, 'shopping.order.Load' );
	}
	function execute( & $request ) {
		$dbo								= $request->getAttribute( 'dbo' );
		$itemNumber					= $request->getParam('item_number','post');
		$orderNumber				= $request->getParam('order_number','post');
		$uploadMethod				= $request->getParam('upload_method','post');
		$shoppingOrderItemObject	= spider_Controller::createObject('shopping_DaoShoppingOrderItem');
		$loginUserObject			= $this->getLoginUserObject( $request );
		$shoppingOrderObject		= $request->getAttribute( 'shopping.order.orderObject' );
		
		if( defined('SHOPPING_ORDER_ITEM_FILE_USE') && '1' == SHOPPING_ORDER_ITEM_FILE_USE ){
		} else {
			$request->addLocaledError('shopping.error.order.file.unavairable',SPIDER_LOG_LEVEL_FATAL,array(''));
			return;
		}
		// 入力の確認
		if( preg_match('/^[0-9]{1,2}$/',$orderNumber) == 0 ) {
			$request->addLocaledError('system.error.common.invalidaccess',SPIDER_LOG_LEVEL_FATAL,array(''));
			return;
		}
		// 編集権限の確認
		if( $this->isLogin( $request ) ) {
			if( SYSTEM_LOGIN_USER_ADMINISTRATORS == $loginUserObject->getLoginGroupLevel() ) {
				// 管理者ログインは編集可
			} else if ( $loginUserObject->getUniqueId() == $shoppingOrderObject->member_id ) {
				// 申込者は編集可
			} else {
				$request->addLocaledError('system.error.login.user.noauthexec',SPIDER_LOG_LEVEL_ERROR,array());
			}
		} else {
			$request->addLocaledError('system.error.login.user.noauthexec',SPIDER_LOG_LEVEL_ERROR,array());
		}
		
		$fileObjectOrgHash	= array();
		if( !$request->isError() ) {
			if( strlen(trim($itemNumber)) > 0 ) {
				// 商品番号が指定されているなら情報読み込み
				if( $dbo->loadByNumber( $shoppingOrderItemObject, $itemNumber ) ) {
				} else {
					$request->addLocaledError('shopping.error.order.file.notfound',SPIDER_LOG_LEVEL_FATAL,array(''));
				}
			} else {
				$request->addLocaledError('shopping.error.order.file.notfound',SPIDER_LOG_LEVEL_FATAL,array(''));
			}
		}
		// エラーがなければファイルアップロード
		if( !$request->isError() ) {
			if( $uploadMethod ) {
				// レンジ登録の場合の処理
				$this->uploadDivided( $request, $shoppingOrderItemObject, $orderNumber );
			} else {
				// phpのpostメソッドファイルアップロードの処理
				$this->uploadNomal( $request, $shoppingOrderItemObject, $orderNumber );
			}
		}
		// 履歴テキストの追記
		$operationType	= 0;
		if( !$request->isError() ){
			$operationType	= $shoppingOrderObject->confirmModifyPermittion( $request, $loginUserObject );
			if( 1 == $operationType || 3 == $operationType ){
			} else {
				// 管理者登録でない場合は管理者にファイルアップロードを通知する
				require_once(dirname(dirname(__FILE__)).'/Optimize.class.php');
				shopping_order_Optimize::_setEnvironmentFor11x( $request, $shoppingOrderObject );
				if( defined('SHOPPING_MAIL_ADDRESS_NOTIFY') && strlen(SHOPPING_MAIL_ADDRESS_NOTIFY) > 0 ) {
					spider_Controller::loadClassDefinition('util_Mail');
					$mailAddressArray	= util_Mail::divideCsvEmail( SHOPPING_MAIL_ADDRESS_NOTIFY );
					foreach( $mailAddressArray as $addNum => $address ) {
						if( $shoppingOrderObject->sendInformationMail( $request, $address, 'SHOPMAILNOTIFYUP', null, '', array(), $loginUserObject ) ) {
						} else {
							$request->addLocaledError('system.error.login.user.failtomail',SPIDER_LOG_LEVEL_FATAL,array(''));
							break;
						}
					}
				}
			}
		}
		$historyNote	= '';
		if( $request->isError() ){
			$historyNote	.= 'エラー '.implode(',',$request->errors);
		} else {
			$historyNote	.= $itemNumber.'にファイルがアップロードされました。';
		}
		if(!$shoppingOrderObject->writeHistoryNote( $request, 'ファイルアップロード', $historyNote, '', $loginUserObject )){
			$request->addLocaledError('shopping.error.order.failtohistory',SPIDER_LOG_LEVEL_FATAL,array(''));
		}
		$request->setAttribute('shopping.order.file.item_object',	$shoppingOrderItemObject);
		$request->setAttribute('shopping.order.file.item_number',	$itemNumber);
		$request->setAttribute('shopping.order.file.order_number',	$orderNumber);
	}
	/**
	 * 通常アップロードの処理
	 */
	function uploadNomal( & $request, & $shoppingOrderItemObject, $orderNumber ) {
		$loginUserObject			= $this->getLoginUserObject( $request );
		$upfile	= & $_FILES['order_item_file'];
		if ( defined('UPLOAD_ERR_INI_SIZE') && UPLOAD_ERR_INI_SIZE == $upfile['error'] ) {
			$request->addLocaledError('system.error.common.upload.overinisize',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if ( defined('UPLOAD_ERR_FORM_SIZE') && UPLOAD_ERR_FORM_SIZE == $upfile['error'] ) {
			$request->addLocaledError('system.error.common.upload.overpostsize',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if ( defined('UPLOAD_ERR_PARTIAL') && UPLOAD_ERR_PARTIAL == $upfile['error'] ) {
			$request->addLocaledError('system.error.common.upload.crushed',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if ( defined('UPLOAD_ERR_NO_FILE') && UPLOAD_ERR_NO_FILE == $upfile['error'] ) {
			$request->addLocaledError('system.error.common.upload.noselect',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if ( defined('UPLOAD_ERR_NO_TMP_DIR') && UPLOAD_ERR_NO_TMP_DIR == $upfile['error'] ) {
			$request->addLocaledError('system.error.common.upload.failtotmpsave',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if ( defined('UPLOAD_ERR_OK') && UPLOAD_ERR_OK != $upfile['error'] ) {
			$request->addLocaledError('system.error.common.upload',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if ( is_uploaded_file($upfile['tmp_name']) ) {
			// ファイルアップロードに問題がないなら 許可された拡張子かチェック
			$isAvailableExtension	= false;
			$fileName		= basename($upfile['name']);
			$fileNameLower	= strtolower($fileName);
			$matches		= array();
			if( preg_match('/\\.(jpg|png|xls|txt|zip|lzh|doc|pdf|ai|eps|ppt)$/',$fileNameLower,$matches) == 0 ) {
				$request->addLocaledError('system.error.common.upload.unknownfile',SPIDER_LOG_LEVEL_FATAL,array(''));
			} else {
				// 許可されているファイル形式なら保存パスに保存
				$saveDirPath	= $shoppingOrderItemObject->getUploadDirPath( $request, true );
				if( $saveDirPath !== false ) {
					$oldFilePath	= $shoppingOrderItemObject->getUploadFilePath( $request, $orderNumber );
					@unlink($oldFilePath);
					$saveFileName	= 'file_'.sprintf('%02d',$orderNumber).$matches[0];
					$savePath		= $saveDirPath.'/'.$saveFileName;
					if( move_uploaded_file($upfile['tmp_name'],$savePath) ) {
						@chmod($savePath,0666);
						$request->setAttribute('shopping.order.file.fileName',	$saveFileName);
					} else {
						$request->addLocaledError('system.error.common.upload.failtomove',SPIDER_LOG_LEVEL_FATAL,array(''));
						return false;
					}
				}
			}
		} else {
			$request->addLocaledError('system.error.common.upload',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		}
		return true;
	}
	/**
	 * POSTで分割アップロードするメソッド
	 */
	function uploadDivided( & $request, & $shoppingOrderItemObject, $orderNumber ) {
		$fileName		= $request->getParam('file_name','post');
		$startPos		= $request->getParam('start_pos','post');
		$contentLength	= $request->getParam('content_length','post');
		$fileLength		= $request->getParam('file_length','post');
		$contentBody	= $request->getParam('content_body','post');
		$fileNameLower	= strtolower($fileName);
		$matches		= array();
		if( preg_match('/\\.(jpg|png|xls|txt|zip|lzh|doc|pdf|ai|eps|ppt)$/',$fileNameLower,$matches) == 0 ) {
			$request->addLocaledError('system.error.common.upload.unknownfile',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if( strlen($contentBody) == 0 ) {
			$request->addLocaledError('system.error.common.upload.noselect',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if( preg_match('/^[0-9]+$/',$startPos) == 0 ) {
			$request->addLocaledError('system.error.common.upload.invalidpos',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if( preg_match('/^[0-9]+$/',$fileLength) == 0 ) {
			$request->addLocaledError('system.error.common.upload.invalidsize',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if( $startPos + $contentLength > $fileLength ) {
			$request->addLocaledError('system.error.common.upload.invalidupsize',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else {
			// 許可されているファイル形式なら保存パスに保存
			$realBody		= base64_decode($contentBody);
			$saveDirPath	= $shoppingOrderItemObject->getUploadDirPath( $request, true );
			if( $saveDirPath !== false ) {
				$saveFileName	= 'file_'.sprintf('%02d',$orderNumber).$matches[0];
				$savePath		= $saveDirPath.'/'.$saveFileName;
				if( $startPos == 0 ) {
					// ファイル頭の場合は新規にオープンして書き込む
					$oldFilePath	= $shoppingOrderItemObject->getUploadFilePath( $request, $orderNumber );
					@unlink($oldFilePath);
					$fp	= @fopen($savePath,'w');
					if( $fp ) {
						if ( @flock($fp, LOCK_EX)) {
							// ファイルを書き込み
							fwrite($fp,$realBody);
							@flock($fp, LOCK_UN);
						} else {
							$request->addLocaledError('system.error.common.file.lock',SPIDER_LOG_LEVEL_FATAL,array(''));
							fclose($fp);
							return false;
						}
						fclose($fp);
					} else {
						$request->addLocaledError('system.error.common.file.openw',SPIDER_LOG_LEVEL_FATAL,array(''));
						return false;
					}
				} else {
					// ファイル冒頭でない場合は存在とタイムスタンプを確認
					if( !file_exists($savePath) ) {
						$request->addLocaledError('system.error.common.invalidaccess',SPIDER_LOG_LEVEL_FATAL,array(''));
						return false;
					} else if( time() - filemtime($savePath) > 60 * 5 ) {
						$request->addLocaledError('system.error.common.session.timeout',SPIDER_LOG_LEVEL_FATAL,array(''));
						return false;
					} else if( filesize($savePath) !== $startPos ) {
						$request->addLocaledError('system.error.common.upload.invaliduporder',SPIDER_LOG_LEVEL_FATAL,array(''));
						return false;
					}
					$fp	= @fopen($savePath,'rw');
					if( $fp ) {
						if ( @flock($fp, LOCK_EX)) {
							// ファイルを書き込み
							fseek($fp,$startPos);
							fwrite($fp,$realBody);
							@flock($fp, LOCK_UN);
						} else {
							$request->addLocaledError('system.error.common.file.lock',SPIDER_LOG_LEVEL_FATAL,array(''));
							fclose($fp);
							return false;
						}
						fclose($fp);
					} else {
						$request->addLocaledError('system.error.common.file.openw',SPIDER_LOG_LEVEL_FATAL,array(''));
						return false;
					}
				}
			}
		}
		$request->setAttribute('shopping.order.file.fileName',	$saveFileName);
		return true;
	}
}
?>