<?php
/* 
 * $Id: edit.inc.php,v 1.4 2004/10/24 08:47:04 youka Exp $
 */



class Cmd_edit
{
	/**
	 * インスタンスを取得する。
	 */
	static function getinstance()
	{
		return new Cmd_edit;
	}
	
	
	/**
	 * 実行する。
	 */
	function run()
	{
		$post = KinoWiki::getinstance()->getPOST();
		if(isset($post['post'])){
			return $this->write();
		}
		
		if(isset($post['preview'])){
			$this->checkparam();
			
			$pagename = resolvepath($post['pagename']);
			$source = $post['source'];
			$notimestamp = (isset($post['notimestamp']) && $post['notimestamp'] == 'on') ? true : false;
			$seed = $post['seed'];
			$body  = "<hr />\n" . convert_block($post['source'], $pagename) . "\n<hr />\n";
			$body .= $this->getpostform($pagename, $source, $notimestamp, $seed);
		}
		else{
			$get = KinoWiki::getinstance()->getGET();
			if(isset($get['page'])){
				$pagename = resolvepath(trim($get['page']));
			}
			else{
				$pagename = resolvepath(DEFAULTPAGE);
			}
			
			$body = $this->getpostform($pagename);
		}
		$ret['title'] = htmlspecialchars($pagename) . ' の編集';
		$ret['body'] = $body;
		$ret['pagename'] = $pagename;
		return $ret;
	}
	
	
	/**
	 * 書き込みフォームを用意する。
	 * 
	 * @param	string	$pagename	ページ名（エンコード無し）
	 * @param	string	$source	ページ内容。
	 * @param	bool	$notimestamp	タイムスタンプ更新なしのオプション
	 * @param	string	$seed	同時更新回避の識別子
	 */
	protected function getpostform($pagename, $source = null, $notimestamp = false, $seed = null)
	{
		if($pagename == ''){
			throw new CmdException('ページ名に空文字列は使えません。', 'edit');
		}
		
		if($source == null){
			$page = Page::getinstance($pagename);
			$source = $page->getsource();
			if($source == ''){
				$templatepage = Page::getinstance(getdirname($pagename) . '/:template');
				$source = $templatepage->getsource();
				$seed = md5('');
			}
		}
		if($seed == null){
			$seed = md5($source);
		}
		
		$smarty = new CmdSmarty('edit');
		$smarty->assign('pagename', $pagename);
		$smarty->assign('source', $source);
		$smarty->assign('seed', $seed);
		$smarty->assign('notimestamp', $notimestamp);
		return $smarty->fetch('edit.tpl.htm');
	}
	
	
	/**
	 * ポストされたデータを元に書き込む。
	 */
	protected function write()
	{
		$this->checkparam();
		
		$post = KinoWiki::getinstance()->getPOST();
		$pagename = resolvepath($post['pagename']);
		$source = $post['source'];
		$seed = $post['seed'];
		$notimestamp = (isset($post['notimestamp']) && $post['notimestamp'] == 'on') ? true : false;
		
		$page = Page::getinstance($pagename);
		if($seed != md5($page->getsource())){
			$ret['title'] = '更新が衝突しました';
			$smarty = new CmdSmarty('edit');
			$smarty->assign('pagename', $pagename);
			$diff = new Text_Diff(explode("\n", $page->getsource()), explode("\n", $source));
			$renderer = new DiffRenderer($diff);
			$smarty->assign('diff', $renderer->render());
			$smarty->assign('form', $this->getpostform($pagename, $source, $notimestamp, md5($page->getsource())));
			$ret['body'] = $smarty->fetch('conflict.tpl.htm');
			return $ret;
		}
		
		//投稿内容に変化がある時のみ更新する
		if(md5(linetrim($source)) != md5($page->getsource())){
			$page->write($source, $notimestamp);
		}
		redirect($pagename);
	}
	
	
	protected function checkparam()
	{
		$post = KinoWiki::getinstance()->getPOST();
		if(!keys_exists($post, array('pagename', 'source', 'seed'))){
			throw new CmdException('パラメータが足りません。', 'edit');
		}
		if($post['pagename'] == ''){
			throw new CmdException('ページ名に空文字列は使えません。', 'edit');
		}
	}
}

?>