<?php
/*
 * file/DaoFileBin.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(__FILE__)
.DIRECTORY_SEPARATOR.'PackageConfig.class.php' );
require_once( dirname( dirname( __FILE__ ) )
.DIRECTORY_SEPARATOR.'database2'
.DIRECTORY_SEPARATOR.'AbstractData.class.php' );
require_once( dirname( dirname( __FILE__ ) )
.DIRECTORY_SEPARATOR.'system'
.DIRECTORY_SEPARATOR.'DataFileWriter.class.php' );
require_once( dirname( dirname( __FILE__ ) )
.DIRECTORY_SEPARATOR.'util'
.DIRECTORY_SEPARATOR.'LockProcess.class.php' );
require_once( dirname( dirname( __FILE__ ) )
.DIRECTORY_SEPARATOR.'util'
.DIRECTORY_SEPARATOR.'CharUtility.class.php' );
require_once( dirname( dirname( __FILE__ ) )
.DIRECTORY_SEPARATOR.'util'
.DIRECTORY_SEPARATOR.'File.class.php' );
/**
 * ファイル実体テーブルレコード対応 DAOクラス
 * 
 * @package file ファイル登録パッケージ
 * @version 1.1.01
 * @author  <m_nakashima@users.sourceforge.jp>
 * @since PHP 4.3
 */
class file_DaoFileBin extends database2_AbstractData {
	/** ファイルシリアル番号	*/
	var $file_number;
	/** ファイルID	*/
	var $file_id;
	/** ファイル名	*/
	var $file_name;
	/** ファイルサイズ	*/
	var $file_size = 0;
	/** ファイルタイプ	*/
	var $file_type = 0;
	/** 拡張子	*/
	var $extension;
	/** MIMEタイプ	*/
	var $mime_type;
	/** 状態フラグ	*/
	var $status_flag = 1;
	/** 関連テーブル名称	*/
	var $related_table;
	/** 関連フィールド名称	*/
	var $related_field;
	/** 公開フラグ: */
	var $open_flag	= 0;
	/** 対象ユーザーエージェント正規表現	*/
	var $target_agent;
	/** ダウンロード時追加レスポンスヘッダ	*/
	var $response_headers;
	/** 所有者ID	*/
	var $owner_id;
	/** 変更者ID	*/
	var $modifier_id;
	/** 更新日	*/
	var $updated_date;
	/** 登録日	*/
	var $registered_date;
	
	// オブジェクト拡張フィールド
	/** ファイル実体キャッシュディレクトリパス	*/
	var $cacheContentDir	= '';
	/** ファイル実体キャッシュファイルパス	*/
	var $cacheContentPath	= '';
	// 登録用一時情報
	/** 登録用一時ファイルURI	*/
	var $registTmpUri		= '';
	
	/**
	 * コンストラクタ
	 */
	function file_DaoFileBin() {
	}
	/**
	 * 付加情報を読み込みます
	 */
	function loadRelation( $dbo ) {
	}
	/**
	 * 画像かどうか確認します
	 * @deprecated 1.1.00 - 2010/07/16
	 */
	function isImage() {
		if( preg_match( '/[iI][mM][aA][gG][eE]\\/[jJ][pP][eE][gG]/',$this->mime_type) > 0
			|| preg_match( '/[iI][mM][aA][gG][eE]\\/[pP][jJ][pP][eE][gG]/',$this->mime_type) > 0
			|| preg_match( '/[iI][mM][aA][gG][eE]\\/[pP][nN][gG]/',$this->mime_type) > 0
			|| preg_match( '/[iI][mM][aA][gG][eE]\\/[gG][iI][fF]/',$this->mime_type) > 0
		) {
			return true;
		}
		return false;
	}
	/**
	 * オブジェクトに設定されているファイルから画像情報を取得します
	 * 画像でないまたはファイルが存在しない場合はfalseを返します
	 * mime_typeのセットを必要としません。
	 * 
	 */
	function getImageInfo( & $request ) {
		$filePath	= null;
		if( !is_null($this->registTmpUri)
			&& strlen($this->registTmpUri) > 0
			&& system_DataFileWriter::isExists($request,$this->registTmpUri, DIR_NAME_TMP) ) {
			$filePath	= system_DataFileWriter::getRealAbsolutePath( $request, $this->registTmpUri, DIR_NAME_TMP );
		} else {
			$filePath	= $this->getOriginalFilePath($request);
		}
		if( file_exists($filePath) ) {
			return getimagesize($filePath);
		} else {
			return false;
		}
	}
	/**
	 * オリジナルファイルの保存パスを取得します。
	 */
	function getOriginalFilePath( & $request, $create=false ) {
		return $this->getSaveRootPath( $request, $create ).DIRECTORY_SEPARATOR.'original';
	}
	/**
	 * キャッシュオリジナルファイルの保存パスを取得します。
	 */
	function getCacheFilePath( & $request, $create=false ) {
		return $this->getCacheRootPath( $request, $create ).DIRECTORY_SEPARATOR.'original';
	}
	/**
	 * 出力（ダウンロード）ファイルパスを取得します
	 */
	function getOutputFilePath( & $request, $maxWidth=null, $maxHeight=null, $fillColor=null, $quality=null ) {
		// 登録一時ファイル
		if( !is_null($this->registTmpUri)
			&& strlen($this->registTmpUri) > 0
			&& system_DataFileWriter::isExists($request,$this->registTmpUri, DIR_NAME_TMP) ) {
			if( $this->isImage()
				&& ( preg_match('/^[0-9]{1,4}$/',$maxWidth) > 0
				|| preg_match('/^[0-9]{1,4}$/',$maxHeight) > 0 ) ) {
				// リサイズが必要な場合
				$orgTmpPath	= system_DataFileWriter::getRealAbsolutePath( $request, $this->registTmpUri, DIR_NAME_TMP );
				$resizePath	= $orgTmpPath.'.'.$maxWidth.'x'.$maxHeight.'x'.$fillColor;
				if( !file_exists($resizePath) ) {
					if( util_File::resizeImage( $orgTmpPath, $resizePath, $maxWidth, $maxHeight, $fillColor, $quality ) ) {
					} else {
						return $this->getOriginalFilePath($request);
					}
				}
				return $resizePath;
			} else {
				return system_DataFileWriter::getRealAbsolutePath( $request, $this->registTmpUri, DIR_NAME_TMP );
			}
		}
		// 登録済みファイル
		if( $this->isImage()
			&& ( preg_match('/^[0-9]{1,4}$/',$maxWidth) > 0
			|| preg_match('/^[0-9]{1,4}$/',$maxHeight) > 0 ) ) {
			// リサイズが必要な場合はリサイズファイルがなければ作成
			$resizeOrgPath		= $this->getOriginalFilePath($request).'.'.$maxWidth.'x'.$maxHeight.'x'.$fillColor;
			if( !file_exists($resizeOrgPath) ) {
				// リサイズファイルがなければ作成
				$srcPath	= $this->getOriginalFilePath($request,true);
				$distPath	= $resizeOrgPath;
				if( util_File::resizeImage( $srcPath, $distPath, $maxWidth, $maxHeight, $fillColor, $quality ) ) {
				} else {
					return $this->getOriginalFilePath($request);
				}
			}
			if( defined('FILE_USE_CACHE') && FILE_USE_CACHE == '2' ) {
				// キャッシュファイルを利用する設定の場合
				$resizeCachePath	= $this->getCacheFilePath( $request ).'.'.$maxWidth.'x'.$maxHeight.'x'.$fillColor;
				if( !file_exists($resizeCachePath) ) {
					// リサイズのキャッシュがない場合はキャッシュフォルダにコピー
					@copy($resizeOrgPath,$this->getCacheFilePath( $request, true ).'.'.$maxWidth.'x'.$maxHeight.'x'.$fillColor);
				}
				return $resizeCachePath;
			}
			return $resizeOrgPath;
		} else {
			// リサイズが不要の場合
			if( defined('FILE_USE_CACHE') && FILE_USE_CACHE == '2' ) {
				$cachePath	= $this->getCacheFilePath( $request );
				if( !file_exists($cachePath) ) {
					@copy($this->getOriginalFilePath($request),$this->getCacheFilePath( $request, true ));
				}
				return $cachePath;
			}
			return $this->getOriginalFilePath($request);
		}
	}
	/**
	 * オリジナル画像ファイルのリサイズ版を作成します
	 */
	function _createResizedFile( & $request, $maxWidth, $maxHeight, $fillColor=null, $quality=null ) {
		if( !$this->isImage() ) {
			return false;
		}
		$orgFilePath	= $this->getOriginalFilePath($request);
	}
	/**
	 * 画像解像度制限
	 */
	function resizeImage( $maxWidth, $maxHeight, $fillColor=null, $quality=null ) {
		if( !$this->isImage() ) {
			return false;
		}
		if( $maxWidth > 0 || $maxHeight > 0 ) {
			list($orgWidth, $orgHeight) = getimagesize($this->cacheContentPath);
			$regWidth	= $orgWidth;
			$regHeight	= $orgHeight;
			if( $maxWidth > 0 && $maxWidth < $orgWidth ) {
				// 横幅が大きいなら調整する
				$regHeight	= $orgHeight * ( $maxWidth / $orgWidth );
				$regWidth	= $maxWidth;
			}
			if( $maxHeight > 0 && $maxHeight < $regHeight ) {
				$regWidth	= $regWidth * ( $maxHeight / $regHeight );
				$regHeight	= $maxHeight;
			}
			if( $regHeight != $orgHeight || $regWidth != $orgWidth ) {
				// どちらかのサイズが変更されていればサイズ変更
				$orgImage = null;
				if ( preg_match( '/[pP][nN][gG]/', $this->mime_type) > 0 ) {
					$orgImage = imagecreatefrompng($this->cacheContentPath);
				} else if ( preg_match( '/[gG][iI][fF]/', $this->mime_type) > 0 ) {
					$orgImage = imagecreatefromgif($this->cacheContentPath);
				} else if ( preg_match( '/[jJ][pP]([eE]|)[gG]/', $this->mime_type) > 0 ) {
					$orgImage = imagecreatefromjpeg($this->cacheContentPath);
				}
				// サイズ変更
				$thumbImage	= null;
				$posX		= 0;
				$posY		= 0;
				if( preg_match('/^[0-9a-fA-F]{6}$/',$fillColor) > 0 ) {
					// フィルをする場合
					if ( preg_match( '/[gG][iI][fF]/', $this->mime_type) > 0 ) {
						$thumbImage	= imagecreate( $maxWidth, $maxHeight );
					} else {
						$thumbImage	= imagecreatetruecolor( $maxWidth, $maxHeight );
					}
					$colR		= hexdec( substr($fillColor, 0, 2) );
					$colG		= hexdec( substr($fillColor, 2, 2) );
					$colB		= hexdec( substr($fillColor, 4, 2) );
					$fillColor	= imagecolorallocate( $thumbImage, $colR, $colG, $colB );
					imagefill( $thumbImage, 0, 0, $fillColor );
					$posX		= ( $maxWidth - $regWidth ) / 2;
					$posY		= ( $maxHeight - $regHeight ) / 2;
				} else {
					if ( preg_match( '/[gG][iI][fF]/', $this->mime_type) > 0 ) {
						$thumbImage	= imagecreate( $regWidth, $regHeight );
					} else {
						$thumbImage	= imagecreatetruecolor( $regWidth, $regHeight );
					}
				}
				// 元画像の透明色を取得して背景色を透明に設定
				imagealphablending($thumbImage,false);
				imageSaveAlpha($thumbImage,true);
				$transX	= 0;
				$transY	= 0;
				$transeColorIndex	= @imagecolortransparent($orgImage);
				$isExistTrans		= false;
				if( $transeColorIndex !== false ) {
					for( $transX=0; $transX<$orgWidth; $transX++ ) {
						for( $transY=0; $transY<$orgHeight; $transY++ ) {
							if( imagecolorat($orgImage,$transX,$transY) == $transeColorIndex ) {
								$isExistTrans	= true;
								break;
							}
						}
						if( $isExistTrans ) {
							break;
						}
					}
					if( $isExistTrans ) {
						$transX	= ceil($transX * ($regWidth/$orgWidth));
						$transY	= ceil($transY * ($regHeight/$orgHeight));
						$rgb = imagecolorat($thumbImage,$transX,$transY);
						$r = ($rgb >> 16) & 0xFF;
						$g = ($rgb >> 8) & 0xFF;
						$b = $rgb & 0xFF;
						$transColor	= imagecolorclosest($thumbImage, $r, $g, $b); 
						imagefill($thumbImage,0,0,$transColor);
						imagecolortransparent($thumbImage,$transColor);
					}
				}
				// エラーがないならリサイズ
				imagecopyresampled($thumbImage, $orgImage
					, $posX, $posY					// サムネイル側開始位置
					, 0, 0							// オリジナル側開始位置
					, $regWidth, $regHeight			// サムネイル側終了位置
					, $orgWidth, $orgHeight );		// オリジナル側終了位置
				if( $isExistTrans ) {
					$rgb = imagecolorat($thumbImage,$transX,$transY);
					$r = ($rgb >> 16) & 0xFF;
					$g = ($rgb >> 8) & 0xFF;
					$b = $rgb & 0xFF;
					$transColor	= imagecolorclosest($thumbImage, $r, $g, $b); 
					imagefill($thumbImage,0,0,$transColor);
					imagecolortransparent($thumbImage,$transColor);
				}
				if( is_writable($this->cacheContentPath) ) {
				} else {
					// 現在指定されている登録用キャッシュファイルに書き込み権限がない場合は一時ファイルにする
					$this->cacheContentPath	= DIR_PATH_TMP.DIRECTORY_SEPARATOR.'file';
					if( !file_exists($this->cacheContentPath) ) {
						if( @mkdir($this->cacheContentPath,0777) ) {
							@chmod($this->cacheContentPath,0777);
						}
					}
					$this->cacheContentPath	.= DIRECTORY_SEPARATOR.'resize';
					if( !file_exists($this->cacheContentPath) ) {
						if( @mkdir($this->cacheContentPath,0777) ) {
							@chmod($this->cacheContentPath,0777);
						}
					}
					$this->cacheContentPath	.= DIRECTORY_SEPARATOR.date('Ymdhis')
						.util_CharUtility::get_rundom_large_char(12);
				}
				// 変更したファイルで上書き
				if ( preg_match( '/[pP][nN][gG]/', $this->mime_type) ) {
					imagepng( $thumbImage, $this->cacheContentPath, 0 );
				} else if ( preg_match( '/[gG][iI][fF]/', $this->mime_type) ) {
					imagegif( $thumbImage, $this->cacheContentPath );
				} else {
					imagejpeg( $thumbImage, $this->cacheContentPath, 100 );
				}
				$orgImage	= null;
				$thumbImage	= null;
			}
		}
		return true;
	}
	/**
	 * 保存ディレクトリパスを取得します
	 */
	function getSaveRootPath( & $request, $create=false ) {
		if( !defined('FILE_SAVE_PATH')
			|| strlen(FILE_SAVE_PATH) == 0
			|| !file_exists(FILE_SAVE_PATH)
			|| !is_writable(FILE_SAVE_PATH) ) {
			// 保存ディレクトリが未設定または書込不能ならエラー
			$request->addError('登録ファイル保存ディレクトリが指定されていないか書込できません。');
			return false;
		}
		$saveRoot	= FILE_SAVE_PATH;
		$filePackageConfig	= null;
		if( $create && !file_exists( $saveRoot ) ) {
			if( @mkdir( $saveRoot, 0777 ) ) {
				@chmod( $saveRoot, 0777 );
			} else {
				return false;
			}
		}
		$saveRoot	.= DIRECTORY_SEPARATOR.'registed';
		if( $create && !file_exists( $saveRoot ) ) {
			if( @mkdir( $saveRoot, 0777 ) ) {
				@chmod( $saveRoot, 0777 );
			} else {
				return false;
			}
		}
		for( $i=0; $i<strlen($this->file_id); $i+=2 ) {
			$dirName	= substr( $this->file_id, $i, 2 );
			if( strlen( $dirName ) > 0 ) {
				$saveRoot	.= DIRECTORY_SEPARATOR.$dirName;
				if( $create && !file_exists($saveRoot) ) {
					if( @mkdir( $saveRoot, 0777 ) ) {
						@chmod( $saveRoot, 0777 );
					} else {
						return false;
					}
				}
			}
		}
		return $saveRoot;
	}
	/**
	 * キャッシュディレクトリパスを取得します
	 */
	function getCacheRootPath( & $request, $create=false ) {
		$cacheRoot	= DIR_PATH_CACHE.DIRECTORY_SEPARATOR.'file';
		if( $create && !file_exists( $cacheRoot ) ) {
			if( @mkdir( $cacheRoot, 0777 ) ) {
				@chmod( $cacheRoot, 0777 );
			} else {
				return false;
			}
		}
		$cacheRoot	.= DIRECTORY_SEPARATOR.'cache';
		if( $create && !file_exists( $cacheRoot ) ) {
			if( @mkdir( $cacheRoot, 0777 ) ) {
				@chmod( $cacheRoot, 0777 );
			} else {
				return false;
			}
		}
		for( $i=0; $i<strlen($this->file_id); $i+=2 ) {
			$dirName	= substr( $this->file_id, $i, 2 );
			if( strlen( $dirName ) > 0 ) {
				$cacheRoot	.= DIRECTORY_SEPARATOR.$dirName;
				if( $create && !file_exists($cacheRoot) ) {
					if( @mkdir( $cacheRoot, 0777 ) ) {
						@chmod( $cacheRoot, 0777 );
					} else {
						return false;
					}
				}
			}
		}
		return $cacheRoot;
	}
	/**
	 * 関連ファイルを全て消去します
	 */
	function deleteFileAll( & $request ) {
		// キャッシュファイルを削除
		$targetDir	= $this->getCacheRootPath( $request, false ); 
		while( strlen($targetDir) > strlen(DIR_PATH_CACHE.DIRECTORY_SEPARATOR.'file'.DIRECTORY_SEPARATOR) ) {
			if( is_dir($targetDir) ) {
				$hasChildDir	= false;
				if ($dh = opendir($targetDir)) {
					while (($fileName = readdir($dh)) !== false) {
						if( '.' != trim($fileName) && '..' != trim($fileName) ) {
							$filePath	= $targetDir.DIRECTORY_SEPARATOR.$fileName;
							$fileType	= filetype($filePath);
							if( preg_match( '/[dD][iI][rR]/', $fileType ) > 0 ) {
								$hasChildDir	= true;
							} else {
								@unlink( $filePath );
							}
						}
					}
					closedir($dh);
					if( !$hasChildDir ) {
						@rmdir( $targetDir );
						$targetDir	= dirname( $targetDir );
					} else {
						break;
					}
				} else {
					break;
				}
			} else {
				break;
			}
		}
		// パブリックキャッシュがあるなら削除
		$openUri	= FILE_PUBLIC_CACHE_FILE_URI;
		if( strlen($this->file_id) > 2 && strlen($this->file_id) % 2 == 0 ) {
			// ファイルIDが2桁以上で2で割れる桁数の時
			for( $i=0; $i<strlen($this->file_id); $i=$i+2 ) {
				$dirName	= substr($this->file_id,$i,2);
				$openUri	.= $dirName.'/';
			}
			system_DataFileWriter::deleteDir( $request, $openUri, 'public' );
		} else if( strlen($this->file_id) > 0 ) {
			$deleteRegx	= '/^'.$this->file_id.'x(|[0-9]{1,4})x(|[0-9]{1,4})/';
			$fileNameArray	= scandir(system_DataFileWriter::getRealAbsolutePath($request,FILE_PUBLIC_CACHE_FILE_URI,'public'));
			foreach( $fileNameArray as $fileName ) {
				if( preg_match($deleteRegx,$this->file_id) > 0 ){
					system_DataFileWriter::delete( $request,FILE_PUBLIC_CACHE_FILE_URI.$fileName,'public');
				}
			}
		}
		// 実ファイルを削除
		$targetDir	= $this->getSaveRootPath( $request, false ); 
		while( strlen($targetDir) > strlen(DIR_PATH_DATA.DIRECTORY_SEPARATOR.'file'.DIRECTORY_SEPARATOR) ) {
			if( is_dir($targetDir) ) {
				$hasChildDir	= false;
				if ($dh = opendir($targetDir)) {
					while (($fileName = readdir($dh)) !== false) {
						if( '.' != trim($fileName) && '..' != trim($fileName) ) {
							$filePath	= $targetDir.DIRECTORY_SEPARATOR.$fileName;
							$fileType	= filetype($filePath);
							if( preg_match( '/[dD][iI][rR]/', $fileType ) > 0 ) {
								$hasChildDir	= true;
							} else {
								@unlink( $filePath );
							}
						}
					}
					closedir($dh);
					if( !$hasChildDir ) {
						@rmdir( $targetDir );
						$targetDir	= dirname( $targetDir );
					} else {
						break;
					}
				} else {
					break;
				}
			} else {
				break;
			}
		}
		return true;
	}
	//
	// 静的メソッド
	//
	function getPublicCacheUri( & $request, $fileId, $maxWidth=null, $maxHeight=null) {
		$openUri	= FILE_PUBLIC_CACHE_FILE_URI;
		$fileId		= trim($fileId);
		if( strlen($fileId) == 0 ) {
			return '';
		} else if( strlen($fileId) > 2 && strlen($fileId) % 2 == 0 ) {
			for( $i=0; $i<strlen($fileId); $i=$i+2 ) {
				$dirName	= substr($fileId,$i,2);
				$openUri	.= $dirName.'/';
			}
			$openUri	.= $maxWidth.'x'.$maxHeight.'.';
		} else {
			$openUri	.= $fileId.'x'.$maxWidth.'x'.$maxHeight.'.';
		}
		if( system_DataFileWriter::isExists($request, $openUri.'jpg', 'public') ) {
			return $openUri.'jpg';
		} else if( system_DataFileWriter::isExists($request, $openUri.'gif', 'public') ) {
			return $openUri.'gif';
		} else if( system_DataFileWriter::isExists($request, $openUri.'png', 'public') ) {
			return $openUri.'png';
		} else if( system_DataFileWriter::isExists($request, $openUri.'swf', 'public') ) {
			return $openUri.'swf';
		}
		$imageUri	= '/file/download.php?fi='.$fileId;
		if( preg_match('/^[0-9]{1,4}$/',$maxWidth) > 0 && $maxWidth > 0 ) {
			$imageUri	.= '&w='.$maxWidth;
		}
		if( preg_match('/^[0-9]{1,4}$/',$maxHeight) > 0 && $maxHeight > 0 ) {
			$imageUri	.= '&h='.$maxHeight;
		}
		return $imageUri;
	}
}
?>