<?php
/**
* @copyright ICZ Corporation (http://www.icz.co.jp/)
* @license See the LICENCE file
* @author <sencha@icz.co.jp>
* @version $Id$
*/

/*
 * ファイルモデル
 */
class Storage extends AppModel{
    // CONST
    const STATUS_PRIVATE         = 0; // 非公開
    const STATUS_PUBLIC          = 1; // 公開

	var $name =	'Storage';
	var $useTable = 'T_FILE';
	var $primaryKey = 'FLE_ID';

	var $belongsTo = array('User' =>
		array(
			'className'		=>	'User',
			'conditions'	=>	'',
			'order'			=>	'',
			'dependent'		=>	true,
			'foreignKey'	=>	'USR_ID',
		),
		'Group' =>
		array(
		'className'		=>	'Group',
		'conditions'	=>	'',
		'order'			=>	'',
		'dependent'		=>	true,
		'foreignKey'	=>	'GRP_ID',
		),
	);

	var $order = array('Storage.INSERT_DATE DESC');

	/*
	 * Save_File($m_class,$_data,$_user,$_grpid)
	 * $m_class アップロードされた場所
	 * $_data 保存したいデータ
	 * $_user ユーザID
	 * $_grpid グループのID
	 * $_public 非公開=0, 公開=1
	 */
	Public Function Save_File($m_class,$_data,$_user,$_grpid,$_public=1,&$error=null){
		$params = array();
		$coment = null;

		//保存場所の設定
		$root= $_user['User']['DIRECTORY1']."/".$_user['User']['DIRECTORY2']."/storage/";

		//トランザクションの開始
		$dataSource = $this->getDataSource();
		$dataSource->begin($this);

		//データの調整
		if (!isset($_data['Storage'])) {
			$_data['Storage']['FILE'] = $_data['FILE'];
		}

		//コメントがある場合
		if (isset($_data['Timeline']['MESSAGE']) &&
				  $_data['Timeline']['MESSAGE']) {
			$coment = $_data['Timeline']['MESSAGE'];
		}
		$maxsize = Configure::read('FILE_ONE_MAX');

		//ファイルがアップロードされたかどうかの確認
		if ($_data['Storage']['FILE']['size'] > 0) {
			if (is_uploaded_file($_data['Storage']['FILE']['tmp_name'])) {
				if ($_data['Storage']['FILE']['size'] < $maxsize) {
					//アップロードされたファイルをランダムで改訂
					$file_name = Security::hash(uniqid().mt_rand());
					$file_name = substr($file_name, 0, 10);

					//ファイルのリサイズ処理
					$this->Image_Resize($_data['Storage']['FILE'],APP."files/user/".$root.$file_name."_thum",'storage_thumbnail');
					$this->Image_Resize($_data['Storage']['FILE'],APP."files/user/".$root.$file_name."_pre",'storage_preview');

					//アップロード
					if (move_uploaded_file($_data['Storage']['FILE']['tmp_name'],APP."files/user/".$root.$file_name)) {
						$extension = strtolower(pathinfo($_data['Storage']['FILE']['name'], PATHINFO_EXTENSION));

						//データの保存
						$params['ORIGINAL_NAME'] = $_data['Storage']['FILE']['name'];
						$params['RAND_NAME'] = $file_name;
						$params['EXTENSION'] = $extension;
						$params['USR_ID'] = $_user['User']['USR_ID'];
						$params['GRP_ID'] = $_grpid;
						$ver = phpversion();
						if ($ver > 5.29) {
							$info = new FInfo(FILEINFO_MIME_TYPE);
							$params['F_TYPE'] = $info->file(APP."files/user/".$root.$file_name);
						} else {
							if ($_data['Storage']['FILE']['type']==='image/jpeg'        ||
								$_data['Storage']['FILE']['type']==='image/gif'			||
								$_data['Storage']['FILE']['type']==='image/pjpeg'		||
								$_data['Storage']['FILE']['type']=== 'image/png'		||
								$_data['Storage']['FILE']['type']=== 'image/x-png')
							{
								$info = getimagesize(APP."files/user/".$root.$file_name);
								if ($info) {
									$params['F_TYPE'] = $info['mime'];
								} else {
									return false;
								}
							} else {
								$params['F_TYPE'] = $_data['Storage']['FILE']['type'];
							}
						}
						$params['F_SIZE'] = $_data['Storage']['FILE']['size'];

						//アップロード場所がタイムラインの場合
						if ($m_class == 'Profile' ||
							$m_class=='Home'      ||
							$m_class=='Group'     ||
							$m_class=='Note') {
							$params['PUBLIC'] = $_public;
						}

						//一覧に表示するかどうか
						if($m_class=='Note') {
							$params['DISP'] = 0;
						}
						else {
							$params['DISP'] = 1;
						}

						$params['INSERT_DATE'] = date("Y-m-d H:i:s");
						$params['LAST_UPDATE'] = date("Y-m-d H:i:s");

						if ($result = $this->save($params)) {
							//タイムラインモデルの取得
							App::import('Model','Timeline');
							$Timeline = new Timeline;
							//タイムラインにアップロードした情報を書き込み
							if ($m_class=='Note') {
								$dataSource->commit($this);
								return $file_name;
							} else if ($id = $Timeline->Save_File($result, $_user, $this->getInsertID(), $m_class, $coment)) {
								//成功
								$dataSource->commit($this);
								return true;
							} else {
								//失敗
								unlink(APP."files/user/".$root.$file_name);
								$dataSource->rollback($this);
								return false;
							}
						} else {
							//失敗
							unlink(APP."files/user/".$root.$file_name);
							$dataSource->rollback($this);
							return false;
						}
					}
				}
				$error=1;
			}
		}
		//失敗
		$dataSource->rollback($this);
		return false;
	}

	/* Get_File($_userid,$frag=null,$_grpid=null)
	 * ファイル取得のための関数
	 * $user_id ユーザーのID
	 * $frag
	 * $_grpid グループID
	 *
	 *return $conditions ページングのための条件
	 */
	Public Function Get_File($_userid, $frag=null, $_user=null){
		$result = array();
        // 自分のファイル or not
		if (!$frag) {
            // 自分のファイル
			$result = array(
					'Storage.USR_ID' => $_userid,
					'Storage.DISP' => 1,
					'Storage.DEL_FLG' => '0'
			);
		} else {
            // 管理者 or not
            if ($_user['User']['AUTHORITY'] != 0) {
                // 公開されている全てのファイルが対象
                // 対象外は
                // ・非公開ステータスのファイル(自分の非公開ファイルも)
                // ・非公開グループのファイル
                $result = array(
                    'or' => array(
                        '1' => array(
                        		'Group.TYPE'=>array(0, 2),
                        		'Storage.PUBLIC'=>1,
                        		'Storage.DEL_FLG'=>0,
         				        'Storage.DISP' => 1,
                        		'User.STATUS'=>1
                        ),
                    )
                );
			}else{
                // 全てのファイル
				$result = array(
					'Storage.DISP' => 1
				);
			}
		}
		return $result;
	}

	/*  Delete_File($_fleid,$_user)
	 * ファイル削除の関数
	 *
	 * $_fileid ファイルのID
	 * $_user ユーザの情報
	 *
	 * return 成功の場合そのID
	 * 		  失敗の場合 'false'
	 *	 	  権限がない場合 'not'
	 */
	Public Function Delete_File($_fleid,$_user=null) {
		//ファイルの情報の取得
		$result = $this->find('first', array(
				'conditions' => array(
						'Storage.FLE_ID'=>$_fleid
				),
				'fields'=>'Storage.USR_ID,
				Storage.FLE_ID,
				Storage.RAND_NAME'
		));
		if ($result['Storage']['USR_ID'] == $_user['User']['USR_ID'] ||
			$_user['User']['AUTHORITY'] ==0 ) {
			//自分が所有しているファイルだったら

			//トランザクションの開始
			$dataSource = $this->getDataSource();
			$dataSource->begin($this);

			//データベース情報の削除
			if ($this->delete($_fleid, false)) {
				if (!file_exists(APP."files/user/".$_user['User']['DIRECTORY1']."/".$_user['User']['DIRECTORY2']."/storage/".$result['Storage']['RAND_NAME'])) {
					//ファイルが存在しない場合
					$dataSource->commit($this);
					return $_fleid;
				}
				//ファイルの削除
				if(unlink(APP."files/user/".$_user['User']['DIRECTORY1']."/".$_user['User']['DIRECTORY2']."/storage/".$result['Storage']['RAND_NAME'])){
					if(file_exists(APP."files/user/".$_user['User']['DIRECTORY1']."/".$_user['User']['DIRECTORY2']."/storage/".$result['Storage']['RAND_NAME']."_thum")){
						unlink(APP."files/user/".$_user['User']['DIRECTORY1']."/".$_user['User']['DIRECTORY2']."/storage/".$result['Storage']['RAND_NAME']."_thum");
					}
					if(file_exists(APP."files/user/".$_user['User']['DIRECTORY1']."/".$_user['User']['DIRECTORY2']."/storage/".$result['Storage']['RAND_NAME']."_pre")){
						unlink(APP."files/user/".$_user['User']['DIRECTORY1']."/".$_user['User']['DIRECTORY2']."/storage/".$result['Storage']['RAND_NAME']."_pre");
					}
					//成功
					$dataSource->commit($this);
					return $_fleid;
				}else{
					//失敗
					$dataSource->rollback($this);
					return 'false';
				}
			}else{
				$dataSource->rollback($this);
				return 'false';
			}
		}else{
			return 'not';
		}
	}

	/* Image_Resize($data,$path,$status=null)
	 * 画像のリサイズ処理
	 *
	 * $_data リサイズするデータ
	 * $path アップロード先
	 * $status 変更画像の種類
	 *
	 * return なし
	 */
	Public Function Image_Resize($data,$path,$status=null) {
		//IE用拡張子判断
		$extension = strtolower(pathinfo($data['name'], PATHINFO_EXTENSION));
		$img_size = Configure::read('IMAGE_SIZE');
		if($extension==='png'||$extension==='jpeg'||$extension==='jpg'||$extension==='gif'){
			//画像typeであるか確認
			if ($data['type']==='image/jpeg'	||
			$data['type']==='image/gif'			||
			$data['type']==='image/pjpeg'		||
			$data['type']=== 'image/png'		||
			$data['type']=== 'image/x-png'){
				if($data['type']==='image/pjpeg'){
					$data['type']='image/jpeg';
				}
				if($data['type']==='image/x-png'){
					$data['type']='image/png';
				}
				$info=getimagesize($data['tmp_name']);
				//正しい画像ファイルであるかを確認
				if($info['mime']==$data['type']){

					//画像のサイズを取得
					list($o_width, $o_height) = getimagesize($data['tmp_name']);
					if($data['type']==='image/jpeg' ){
						$image = imagecreatefromjpeg($data['tmp_name']);
					}
					else if($data['type']==='image/png' ){
						$image = imagecreatefrompng($data['tmp_name']);
					}
					else if($data['type']==='image/gif' ){
						$image = imagecreatefromgif($data['tmp_name']);
					}
					//縦長か横長かをチェック
					if($o_width > $o_height){
						//横長の場合
						if($status=='storage_thumbnail'){
							$rate = $img_size['Storage']['thumbnail'][0]/$o_width;
						}elseif($status=='storage_preview'){
							$rate = $img_size['Storage']['preview'][0]/$o_width;
						}
						if($status=='thumbnail'){
							$rate = $img_size['User']['thumbnail'][0]/$o_width;
						}elseif($status=='preview'){
							$rate = $img_size['User']['preview'][0]/$o_width;
						}
						if($rate>1){
							$height = $o_height;
							$width = $o_width;
						}else{
							$height = $o_height * $rate;
							$width = $o_width * $rate;
						}
						if($height<1){
							$height=1;
						}
						}else{//縦長の場合
						if($status=='storage_thumbnail'){
							$rate = $img_size['Storage']['thumbnail'][1]/$o_height;
						}elseif($status=='storage_preview'){
							$rate = $img_size['Storage']['preview'][1]/$o_height;
						}
						if($status=='thumbnail'){
							$rate = $img_size['User']['thumbnail'][1]/$o_height;
						}elseif($status=='preview'){
							$rate = $img_size['User']['preview'][1]/$o_height;
						}
						if($rate>1){
							$height = $o_height;
							$width = $o_width;
						}else{
							$height = $o_height * $rate;
							$width = $o_width * $rate;
						}
						if($width<1){
							$width=1;
						}
					}
					$new_image = ImageCreateTrueColor($width, $height);
					if($status=='storage_thumbnail'||$status=='storage_preview'){
						if($data['type']==='image/jpeg' ){
							ImageCopyResampled($new_image,$image,0,0,0,0,$width,$height,$o_width,$o_height);
							ImageJPEG($new_image, $path, 100);
						}else{
							imagealphablending($new_image,false);
							imageSaveAlpha($new_image,true);
							$fillcolor = imagecolorallocatealpha($new_image,0,0,0,127);
							imagefill($new_image,0,0,$fillcolor);
							ImageCopyResampled($new_image,$image,0,0,0,0,$width,$height,$o_width,$o_height);
							Imagepng($new_image, $path);
						}
						imagedestroy($image);
						imagedestroy($new_image);
					}else{
						if($status=='thumbnail'){
							$tmp_image = ImageCreateTrueColor($img_size['User']['thumbnail'][0],$img_size['User']['thumbnail'][1]);
							$x = ($img_size['User']['thumbnail'][0]-$width)/2;
							$y = ($img_size['User']['thumbnail'][1]-$height)/2;
						}
						if($status=='preview'){
							$tmp_image = ImageCreateTrueColor($img_size['User']['preview'][0],$img_size['User']['preview'][1]);
							$x = ($img_size['User']['preview'][0]-$width)/2;
							$y = ($img_size['User']['preview'][1]-$height)/2;
						}
						$img = ImageCreateTrueColor($o_width, $o_height);
						$color = imagecolorallocate($img, 255, 255, 255);
						for($x_line = 0 ; $x_line < $o_width ; $x_line++){
							for($y_line = 0 ; $y_line < $o_height ; $y_line++){
								//インデックスの取得
								$index = imagecolorat($image , $x_line  , $y_line);
								//色情報の取得
								$image_data = imagecolorsforindex($image, $index);
								$alpha = $image_data['alpha'];
								$col_tmp = imagecolorallocate($img, $image_data['red'],$image_data['green'],$image_data['blue']);
								//色情報の取得
								if($alpha == 127)
								{
									//ピクセルの描画
									imagesetpixel($img, $x_line, $y_line, $color);
								}else{
									imagesetpixel($img, $x_line, $y_line, $col_tmp);
								}
							}
						}
						$backcol = imagecolorallocate($tmp_image, 255, 255, 255);
						imagefill($tmp_image, 0, 0, $backcol);
						ImageCopyResampled($new_image,$img,0,0,0,0,$width,$height,$o_width,$o_height);
						imagecopy($tmp_image,$new_image,$x,$y,0,0,$width,$height);
						ImageJPEG($tmp_image, $path, 100);
						imagedestroy($img);
						imagedestroy($image);
						imagedestroy($new_image);
						imagedestroy($tmp_image);
					}
				}
			}
		}
	}
	/* Change_Public($_fleid,$_user)
	 * 公開ステータス変更の関数
	 * $_fleid ファイルのID
	 * $_user ユーザの情報
	 *
	 * return 保存した結果
	 */
	Function Change_Public($_fleid,$_user) {
		//ファイル情報の取得
		$result = $this->find('first', array(
				'fields' => array(
						'FLE_ID',
						'PUBLIC'
				),
				'conditions' => array(
						'Storage.FLE_ID' => $_fleid,
						'Storage.USR_ID' => $_user['User']['USR_ID']
				)
		));

		if (!$result) {
			//情報を取得できなかった場合
			return false;
		}

		if ($result['Storage']['PUBLIC'] == Storage::STATUS_PRIVATE) {
			//現在のステータスが非公開の場合
			$result['Storage']['PUBLIC'] = Storage::STATUS_PUBLIC;
			$this->save($result);
			return $result;
		} elseif ($result['Storage']['PUBLIC'] == Storage::STATUS_PUBLIC) {
			//現在のステータスが公開の場合
			$result['Storage']['PUBLIC'] = Storage::STATUS_PRIVATE;
			$this->save($result);
			return $result;
		}
	}

	Public Function Search_File($_userid, $_name=null, $_all=null) {
		if ($_all == 'all') {

			//参加情報モデルの読み込み
			App::import('Model', 'Join');
			$join = new Join;

			//参加しているグループの取得とリスト化
			$jg = $join->Join_Group($_userid);
			$gid_or = array();
			foreach ($jg as $key => $val) {
				$gid_or[$key] = $val['Join']['GRP_ID'];
			}
			$result = array('or'=>array(
				'1'=>array(
						'Storage.USR_ID' => $_userid,
						'Storage.ORIGINAL_NAME LIKE' => "%$_name%",
						'Storage.DISP' => 1,
						'Storage.DEL_FLG'=>'0'
				),
				'2'=>array(
						'Storage.USR_ID NOT' => $_userid,
						'Group.TYPE' => Group::TYPE_PUBLIC,
						'Storage.PUBLIC' => Storage::STATUS_PUBLIC,
						'Storage.ORIGINAL_NAME LIKE' => "%$_name%",
						'Storage.DEL_FLG'=>'0',
						'Storage.DISP' => 1,
						'User.STATUS'=>1
				),
				'3'=>array(
						'Storage.USR_ID NOT' => $_userid,
						'Group.TYPE' => Group::TYPE_PRIVATE,
						'Group.GRP_ID' => $gid_or,
						'Storage.PUBLIC' => Storage::STATUS_PUBLIC,
						'Storage.ORIGINAL_NAME LIKE' => "%$_name%",
						'Storage.DEL_FLG'=>'0',
						'Storage.DISP' => 1,
						'User.STATUS'=>1
				),
				'4'=>array(
						'Storage.USR_ID NOT' => $_userid,
						'Group.TYPE' => NULL,
						'Storage.PUBLIC' => Storage::STATUS_PUBLIC,
						'Storage.ORIGINAL_NAME LIKE' => "%$_name%",
						'Storage.DEL_FLG'=>'0',
						'Storage.DISP' => 1,
						'User.STATUS'=>1,
				),
				'5'=>array(
						'Storage.USR_ID NOT' => $_userid,
						'Group.TYPE' => Group::TYPE_PERSONAL,
						'Storage.PUBLIC' => Storage::STATUS_PUBLIC,
						'Storage.ORIGINAL_NAME LIKE' => "%$_name%",
						'Storage.DEL_FLG'=>'0',
						'Storage.DISP' => 1,
						'User.STATUS'=>1
				),
			));
		} else {
			$result = array(
					'Storage.USR_ID' => $_userid,
					'Storage.ORIGINAL_NAME LIKE' => "%$_name%",
					'Storage.DISP' => 1,
					'Storage.DEL_FLG'=>'0'
			);
		}
		return $result;
	}
}
