<?php
/**
 * コンテナクラス
 *
 * PHP versions 5
 *
 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
 *
 * @package    Magic3 Framework
 * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
 * @copyright  Copyright 2006-2008 Magic3 Project.
 * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
 * @version    SVN: $Id: admin_mainTemplistWidgetContainer.php 575 2008-05-04 06:14:43Z fishbone $
 * @link       http://www.magic3.org
 */
require_once($gEnvManager->getContainerPath()		. '/baseWidgetContainer.php');
require_once($gEnvManager->getCurrentWidgetDbPath() . '/admin_mainDb.php');
require_once($gEnvManager->getLibPath()				. '/pcl/pclzip.lib.php' );
			
class admin_mainTemplistWidgetContainer extends BaseWidgetContainer
{
	private $db;	// DB接続オブジェクト
	private $newTemplate = array();		// 新規追加テンプレート
	const TEMPLATE_THUMBNAIL_FILENAME = 'template_thumbnail.png';		// テンプレートサムネール
	const previewImageSizeHeight = 27;
	const previewImageSizeWidth = 42;
	const imageSizeHeight = 135;
	const imageSizeWidth = 210;
		
	/**
	 * コンストラクタ
	 */
	function __construct()
	{
		// 親クラスを呼び出す
		parent::__construct();
		
		// DB接続オブジェクト作成
		$this->db = new admin_mainDb();
	}
	/**
	 * テンプレートファイルを設定
	 *
	 * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
	 * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @param object         $param			任意使用パラメータ。そのまま_assign()に渡る
	 * @return string 						テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
	 */
	function _setTemplate($request, &$param)
	{	
		if ($this->db->canDetailConfig()){		// 詳細設定可能なとき
			return 'templist.tmpl.html';
		} else {
			return 'templist_simple.tmpl.html';
		}
	}
	/**
	 * テンプレートにデータ埋め込む
	 *
	 * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
	 *
	 * @param RequestManager $request		HTTPリクエスト処理クラス
	 * @param object         $param			任意使用パラメータ。_setTemplate()と共有。
	 * @param								なし
	 */
	function _assign($request, &$param)
	{
		global $gEnvManager;
		global $gSystemManager;
		
		$act = $request->trimValueOf('act');
		$selectedItemNo = $request->trimValueOf('no');		// 処理対象の項目番号
		$userId = $gEnvManager->getCurrentUserId();
		$serial = $request->trimValueOf('serial');		// シリアルNo
		$templateId = $request->trimValueOf('template');		// テンプレートID

		if ($act == 'readnew'){		// テンプレート再読み込みのとき
			$addTemplateCount = 0;
			// テンプレート一覧取得
			if ($this->db->getAllTemplateIdList($rows)){
				// テンプレートディレクトリチェック
				$searchPath = $gEnvManager->getTemplatesPath();
				if (is_dir($searchPath)){
					$dir = dir($searchPath);
					while (($file = $dir->read()) !== false){
						$filePath = $searchPath . '/' . $file;
						// ディレクトリかどうかチェック
						if (strncmp($file, '.', 1) != 0 && $file != '..' && is_dir($filePath)
							&& strncmp($file, '_', 1) != 0		// 「_」で始まる名前のディレクトリは読み込まない
							&& strcmp($file, 'm') != 0){		// 携帯用のディレクトリ「m」は読み込まない
							// DBに登録されていない場合は登録
							for ($i = 0; $i < count($rows); $i++){
								if ($file == $rows[$i]['tm_id']) break;
							}
							if ($i == count($rows)){
								$ret = $this->db->addNewTemplate($file, $file, $userId);
								if ($ret){
									$this->newTemplate[] = $file;
									$addTemplateCount++;		// テンプレート追加
								}
							}
						}
					}
					$dir->close();
				}
			} else {
			}
			// 終了メッセージを表示
			if ($addTemplateCount > 0){
				$msg = '新規テンプレートを追加しました(追加数=' . $addTemplateCount . ')';
			} else {
				$msg = '新規テンプレートはありません';
			}
			$this->setMsg(self::MSG_GUIDANCE, $msg);
		} else if ($act == 'updateline'){		// 行更新のとき
			// 変更可能値
			$updateName = $request->trimValueOf('item' . $selectedItemNo . '_name');				// 名前
			$updateIsDefault = ($request->trimValueOf('item' . $selectedItemNo . '_isdefault') == 'on') ? 1 : 0;		// デフォルトかどうか
			$ret = $this->db->updateTemplate($serial, $updateName, $userId);
			if ($ret){		// データ更新成功のとき
				$this->setMsg(self::MSG_GUIDANCE, 'データを更新しました');
			} else {
				$this->setMsg(self::MSG_APP_ERR, 'データ更新に失敗しました');
			}
		} else if ($act == 'deleteline'){		// テンプレート削除のとき
			if ($this->db->getTemplate($serial, $row)){
				// テンプレートディレクトリ取得
				$templateId = $row['tm_id'];
				$templatePath = $gEnvManager->getTemplatesPath() . '/' . $templateId;
			
				// ディレクトリ削除
				if ((is_dir($templatePath) && rmDirectory($templatePath)) || !is_dir($templatePath)){// 削除成功か、ディレクトリが存在しないとき
					$ret = $this->db->deleteTemplate($serial, $userId);
					if ($ret){		// データ更新成功のとき
						$this->setMsg(self::MSG_GUIDANCE, 'テンプレートを削除しました');
					} else {
						$this->setMsg(self::MSG_APP_ERR, 'テンプレート削除に失敗しました');
					}
				} else {
					$this->setMsg(self::MSG_APP_ERR, 'テンプレートのディレクトリが削除できませんでした');
				}
			} else {
				$this->setMsg(self::MSG_APP_ERR, '削除対象のテンプレートが見つかりません');
			}
		} else if ($act == 'upload'){		// ファイルアップロードの場合
			// アップロードされたファイルか？セキュリティチェックする
			if (is_uploaded_file($_FILES['upfile']['tmp_name'])) {
				$uploadFilename = $_FILES['upfile']['name'];		// アップロードされたファイルのファイル名取得

				// ファイル名の解析
				$pathParts = pathinfo($uploadFilename);
				$ext = $pathParts['extension'];		// 拡張子
				$templateName = basename($uploadFilename, '.' . $ext);		// 拡張子をはずす
				
				// ファイル拡張子のチェック
				if ($ext != 'zip'){
					$msg = 'zip圧縮のファイルのみアップロード可能です';
					$this->setAppErrorMsg($msg);
				}
				
				if ($this->getMsgCount() == 0){		// エラーが発生していないとき
					// 同名のテンプレートがないかチェック
					if ($this->db->getAllTemplateIdList($rows)){
						for ($i = 0; $i < count($rows); $i++){
							if ($templateName == $rows[$i]['tm_id']) break;
						}
						if ($i < count($rows)){
							$msg = '同名のテンプレートがすでに存在します(テンプレート名：' . $templateName . ')';
							$this->setAppErrorMsg($msg);
						}
					}
				}
				if ($this->getMsgCount() == 0){		// エラーが発生していないとき
					// ファイルを保存するサーバディレクトリを指定
					$tmpFile = tempnam(M3_SYSTEM_WORK_DIR_PATH, M3_SYSTEM_WORK_UPLOAD_FILENAME_HEAD);
		
					// アップされたテンポラリファイルを保存ディレクトリにコピー
					$ret = move_uploaded_file($_FILES['upfile']['tmp_name'], $tmpFile);
					if ($ret){
						// 解凍先ディレクトリ
						$extDir = $gEnvManager->getTemplatesPath();
					
						// zipファイルを解凍
						$zipFile = new PclZip($tmpFile);
						if (($zipList = $zipFile->listContent()) == 0){
							$msg = 'zipファイルの内容のリスト取得に失敗しました(要因: ' . $zipFile->errorName(true) . ')';
							$this->setAppErrorMsg($msg);							
						} else {
							// デバッグ用							
							/*for ($i = 0; $i < sizeof($zipList); $i++) {
								for(reset($zipList[$i]); $key = key($zipList[$i]); next($zipList[$i])) {
									echo "File $i / [$key] = ".$zipList[$i][$key]."<br>";
								}
								echo "<br>";
							}*/
							// zipファイル名とディレクトリ名が同じであるかチェック
							$cmpTemplateName = $templateName . '/';
							if (strncmp($zipList[0]['filename'], $cmpTemplateName, strlen($cmpTemplateName)) == 0){			// bugfix 先頭は必ずしもルートディレクトリ名ではない
								$ret = $zipFile->extract(PCLZIP_OPT_PATH, $extDir);
								if ($ret){
									$ret = $this->db->addNewTemplate($templateName, $templateName, $userId);
								
									$msg = 'ファイルのアップロードが完了しました(テンプレート名：' . $templateName . ')';
									$this->setGuidanceMsg($msg);
									$this->newTemplate[] = $templateName;
								} else {
									$msg = 'ファイルのアップロードに失敗しました(要因: ' . $zipFile->errorName(true) . ')';
									$this->setAppErrorMsg($msg);
								}
							} else {
								$msg = 'zipファイルのファイル名とディレクトリ名が異なっているか、全角文字が含まれています(ファイル名=[' . $zipList[0]['filename'] . '], ディレクトリ名=[' . $cmpTemplateName . '])';
								$this->setAppErrorMsg($msg);
							}
						}
					} else {
						$msg = 'ファイルのアップロードに失敗しました';
						$this->setAppErrorMsg($msg);
					}
					// テンポラリファイル削除
					unlink($tmpFile);
				}
			} else {
				$msg = 'アップロードファイルが見つかりません(要因：アップロード可能なファイルのMaxサイズを超えている可能性があります - ' . $gSystemManager->getMaxFileSizeForUpload() . 'バイト)';
				$this->setAppErrorMsg($msg);
			}
		} else if ($act == 'download'){		// ファイルダウンロードのとき
			$templatesDir = $gEnvManager->getTemplatesPath();		// テンプレートディレクトリ
			$templateDir = $templatesDir . '/' . $templateId;			// ダウンロードするウィジェットのディレクトリ
			$downloadFilename = $templateId . '.zip';		// ダウンロード時のファイル名
			$tmpFile = tempnam(M3_SYSTEM_WORK_DIR_PATH, M3_SYSTEM_WORK_DOWNLOAD_FILENAME_HEAD);		// zip処理用一時ファイル
			
			// zip圧縮
			$zipFile = new PclZip($tmpFile);
			$ret = $zipFile->create($templateDir, PCLZIP_OPT_REMOVE_PATH, $templatesDir);
			if ($ret){
				// ダウンロード処理
				ob_end_clean();
			    header('Content-disposition: attachment; filename=' . $downloadFilename);
			    header('Content-type: application/octet-stream; name=' . $downloadFilename);
			    $fp = fopen($tmpFile, "r");
			    echo fread($fp, filesize($tmpFile));
			    fclose($fp);
				ob_end_flush();
			
				// テンポラリファイル削除
				unlink($tmpFile);
				return;
			} else {
				$msg = 'ファイルのダウンロードに失敗しました(要因: ' . $zipFile->errorName(true) . ')';
				$this->setAppErrorMsg($msg);
				
				// テンポラリファイル削除
				unlink($tmpFile);
			}
		} else if ($act == 'changedefault'){		// デフォルトテンプレートの変更のとき
			$this->db->changeDefaultTemplate($templateId);

			// セッションのテンプレートIDを更新
			$request->setSessionValue(M3_SESSION_CURRENT_TEMPLATE, $templateId);
		}
		// パラメータを設定
		$this->tmpl->addVar("_widget", "install_dir", $gEnvManager->getTemplatesPath());// インストールディレクトリ
		$this->tmpl->addVar("_widget", "admin_url", $gEnvManager->getDefaultAdminUrl());// 管理用URL
				
		// テンプレートリストを取得
		$this->db->getAllTemplateList(array($this, 'tempListLoop'));
	}
	/**
	 * テンプレートリスト、取得したデータをテンプレートに設定する
	 *
	 * @param int $index			行番号(0～)
	 * @param array $fetchedRow		フェッチ取得した行
	 * @param object $param			未使用
	 * @return bool					true=処理続行の場合、false=処理終了の場合
	 */
	function tempListLoop($index, $fetchedRow, $param)
	{
		global $gEnvManager;
				
		// デフォルトテンプレート
		$defaultButton = '';
		if ($fetchedRow['tm_default']){
			$defaultButton = 'checked';
		}
		
		// 画面イメージ表示設定
		$id = $this->convertToDispString($fetchedRow['tm_id']);				// テンプレートID
		$name = $this->convertToDispString($fetchedRow['tm_name']);			// テンプレート名
		$imgUrl = $gEnvManager->getTemplatesUrl() . '/' . $id . '/' . self::TEMPLATE_THUMBNAIL_FILENAME;
		
		/*
		$hasCss = '';
		if ($fetchedRow['wd_read_css']){
			$hasCss = 'checked';
		}
		// 編集不可項目のときは、ボタンを使用不可にする
		$buttonEnabled = '';
		if (!$fetchedRow['wd_editable']) $buttonEnabled = 'disabled';
		*/
		// 行カラーの設定
		$lineColor = '';
		if ($index % 2 != 0){
			$lineColor = 'class="even"';		// 偶数行
		}
		// 新規に追加されたテンプレートかチェック
		$idText = $id;
		for ($i = 0; $i < count($this->newTemplate); $i++){
			if ($this->newTemplate[$i] == $id){
				$idText = '<b><font color="green">' . $id . '</font></b>';
				break;
			}
		}
		//$imageTag = '<a class="thumbnail" href="#"><img src="' . $imgUrl . '" width="' . self::previewImageSizeWidth . '" height="' . self::previewImageSizeHeight . '" border="0" /><span><img src="' . $imgUrl . '" width="' . self::imageSizeWidth . '" height="' . self::imageSizeHeight . '"/></span></a>';
		$imageTag = '<img src="' . $imgUrl . '" width="' . self::previewImageSizeWidth . '" height="' . self::previewImageSizeHeight . '" border="0" />';
		$row = array(
			'line_color' => $lineColor,											// 行のカラー
			'no' => $index + 1,													// 行番号
			'serial' => $this->convertToDispString($fetchedRow['tm_serial']),			// シリアル番号
			//'id_with_image' => $idSpan,			// 画像付きID
			'id_with_image' => $id,
			'id' => $id,			// ID
			'name' => $name,		// 名前
			'update_dt' => $this->convertToDispDateTime($fetchedRow['tm_create_dt']),	// 更新日時
			'is_default' => $defaultButton,										// デフォルトテンプレートかどうか
			'image_tag' => $imageTag		// 画像
		);
		$this->tmpl->addVars('templist', $row);
		$this->tmpl->parseTemplate('templist', 'a');
		return true;
	}
}
?>
