<?php
/*
 * topic/Topic.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');
class topic_Topic extends system_AbstractData {
	// 基本情報
	/** 記事ID	*/
	var $topicId;
	/** 記事題名	*/
	var $subject;
	/** 著者名	*/
	var $author;
	/** カテゴリ	*/
	var $category;
	/** 概要	*/
	var $description;
	/** 本文	*/
	var $body;
	/** テンプレートファイル名	*/
	var $templateFile;
	/** 改行反映フラグ: 0=反映しない, 1=反映する	*/
	var $enableNl2Br	= 1;
	/** HTMLフラグ: 0=無効, 1=有効	*/
	var $enableHtml		= 0;
	/** 画像寄せフラグ: 0=センター, 10=左寄せ, 20=右寄せ*/
	var $alignImage	= 0;
	/** 投稿日時	*/
	var $topicDate;
	/** 最終更新日時	*/
	var $updatedDate;
	/** 作成日時	*/
	var $registeredDate;
	
	/**
	 * Constructor
	 */
	function topic_Topic() {
		$this->topicDate		= date('Y-m-d H:i:s');
		$this->updatedDate		= date('Y-m-d H:i:s');
		$this->registeredDate	= date('Y-m-d H:i:s');
	}
	/**
	 * 表示の為のメンバコンバート
	 */
	function convertForView( & $request ) {
		// 投稿日時
		list( $date, $time )	= explode(' ',$this->topicDate);
		list( $this->topicDate_year, $this->topicDate_month, $this->topicDate_day )
			= explode('-',$date);
		list( $this->topicDate_hour, $this->topicDate_min, $this->topicDate_sec )
			= explode(':',$time);
		// 最終更新日時
		list( $date, $time )	= explode(' ',$this->updatedDate);
		list( $this->updatedDate_year, $this->updatedDate_month, $this->updatedDate_day )
			= explode('-',$date);
		list( $this->updatedDate_hour, $this->updatedDate_min, $this->updatedDate_sec )
			= explode(':',$time);
		// 作成日時
		list( $date, $time )	= explode(' ',$this->registeredDate);
		list( $this->registeredDate_year, $this->registeredDate_month, $this->registeredDate_day )
			= explode('-',$date);
		list( $this->registeredDate_hour, $this->registeredDate_min, $this->registeredDate_sec )
			= explode(':',$time);
		
		return true;
	}
	/**
	 * ユニークIDを取得する
	 */
	function getUniqueId() {
		return $this->topicId;
	}
	/**
	 * データ行を書き込む文字列を取得します
	 */
	function getCsvString() {
		return parent::getCsvString( $GLOBALS['TOPIC_COLUMN_ORDER_DEF_HASH'] );
	}
	/**
	 * CSV形式のデータ行ラインからフィールドに値を設定します
	 */
	function setFieldByCsvLine( $csvLine ) {
		return parent::setFieldByCsvLine( $GLOBALS['TOPIC_COLUMN_ORDER_DEF_HASH'], $csvLine );
	}
	/**
	 * loadメソッドのオーバーライド
	 */
	function load( & $request, $uniqueId ) {
		return parent::load( $request, $uniqueId, 2 );
	}
	/**
	 * saveメソッドのオーバーライド
	 */
	function save( & $request ) {
		if( preg_match('/^[0-9]{4}\\-[0-9]{2}-[0-9]{2}$/',$this->topicDate) > 0 ) {
			// 時分秒がないなら追記しておく
			$this->topicDate	.= ' 00:00:00';
		}
		if( parent::save( $request, 2, true ) ) {
			if( $this->renewIndex( $request ) ) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
	/**
	 * deleteメソッドのオーバーライド
	 */
	function delete( & $request ) {
		if( parent::delete( $request, $this->topicId, 2, true ) ) {
			if( $this->renewIndex( $request, true ) ) {
				return true;
			} else {
				return false;
			}
		}
		return false;
	}
	/**
	 * 本記事の状態に合わせてインデックスファイルの本記事情報を更新します
	 */
	function renewIndex( & $request, $deleteFlag=false ) {
		// 保存に成功したらインデックスファイルを更新
		$thisTopicTime	= strtotime($this->topicDate);
		$topicFilePath	= system_DataFileWriter::getRealAbsolutePath( $request, TOPIC_FILE_URI_TOPICS, DIR_NAME_DATA );
		if( $topicFilePath ) {
			if( !file_exists($topicFilePath) ) {
				if( @touch( $topicFilePath ) ) {
					@chmod( $topicFilePath, 0666 );
				}
			}
			// 一時ファイルパスをオープンしロックして処理
			$topicTmpPath	= $topicFilePath.'.tmp';
			$fpw	= @fopen( $topicTmpPath, 'w' );
			if( $fpw ) {
				if( @flock( $fpw, LOCK_EX ) ) {
					$fpr	= @fopen( $topicFilePath, 'r' );
					if( $fpr ) {
						if( @flock( $fpr, LOCK_SH ) ) {
							$written	= false;
							while (!feof($fpr)) {
								$line = trim(fgets($fpr));
								if( strlen($line) > 0 ) {
									$topicObj	= new topic_Topic();
									$topicObj->setFieldByCsvLine( $line );
									if( $topicObj->topicId == $this->topicId ) {
										// 記事番号が一致する場合書き込まない
									} else {
										// 記事番号が一致しない場合
										$topicTime	= strtotime($topicObj->topicDate);
										if( $topicTime > $thisTopicTime ) {
											// 対象記事の投稿日時がこの記事よりも後の日時の場合はそのまま書き込む
											@fwrite( $fpw, $line."\n" );
										} else {
											// 対象記事の投稿日時がこの記事よりも前の日時の場合
											if( $written ) {
												// 本記事の情報を書き込み済みならそのまま書き込む
												@fwrite( $fpw, $line."\n" );
											} else {
												// 本記事の情報を書き込み済みでないなら書き込んでから書き込み
												if( !$deleteFlag ) {
													@fwrite( $fpw, $this->getCsvString() );
												}
												@fwrite( $fpw, $line."\n" );
												$written	= true;
											}
										}
									}
								}
							}
							if( !$written && !$deleteFlag ) {
								// 最終行まで本記事書き込みが行われなかった場合は書き込み
								@fwrite( $fpw, $this->getCsvString() );
							}
							@flock( $fpr, LOCK_UN );
						} else {
							$request->addError('記事インデックスファイルのロック取得に失敗しました。');
						}
						@fclose( $fpr );
					} else {
						$request->addError('記事インデックスファイルの読み込みオープンに失敗しました。');
					}
					@flock( $fpw, LOCK_UN );
				}
				@fclose( $fpw );
				// 本データファイルを一度削除
				if( file_exists($topicFilePath) ) {
					system_DataFileWriter::delete( $request, TOPIC_FILE_URI_TOPICS, DIR_NAME_DATA );
				}
				// 一時ファイルをインポート
				system_DataFileWriter::import( $request, TOPIC_FILE_URI_TOPICS, $topicTmpPath, $targetRoot=null );
				// エラー有無にかかわらず一時ファイルは削除
				@unlink($topicTmpPath);
			} else {
				$request->addError('一時ファイル書き込みオープンに失敗しました。');
			}
		} else {
			$request->addError('インデックスファイルパスが取得できませんでした。');
		}
		if( $request->isError() ) {
			return false;
		} else {
			return true;
		}
	}
}
?>